elm-community / list-extra

Convenience functions for working with List.
http://package.elm-lang.org/packages/elm-community/list-extra/latest
MIT License
135 stars 59 forks source link

Proposal for `maybeCons` function #58

Open YetAnotherMinion opened 7 years ago

YetAnotherMinion commented 7 years ago

I have found it useful when building views to be able to conditionally include an Attribute or child element. It seem natural to use Maybe to represent this conditional nature. However I usually only have one conditional attribute and several unconditional attributes so it feels a little awkward and overkill to wrap many elements in Just and then call filterMap identity. I would prefer to write the list literal and then conditionally add items.

maybeCons : Maybe a -> List a -> List a
maybeCons maybeItem list =
     case maybeItem of
          Just item -> item :: list
          Nothing -> list

For example when a tabbed container, I want to only attach click handlers to the non selected tabs to simplify my update logic.

let                                                                             
    (editOnClick, previewOnClick) =                                             
    case model.editorTab of                                                     
        Edit draft ->                                                           
            ( Nothing                                                           
            , Just <| onWithOptions                                                     
                "click"                                                         
                (Options True True)                                             
                (Json.Decode.succeed <| SetEditorTab <| Preview draft model.user.theme )
            )                                                                   

        Preview draft theme ->                                                  
            ( Just <| onWithOptions                                                     
                "click"                                                         
                (Options True True)                                             
                (Json.Decode.succeed <| SetEditorTab <| Preview draft model.user.theme )
            , Nothing                                                           
            )                                                                   
in                                                                              
    div [ id Editor ]                                                           
        [ div [ class EditorHeader ]                                            
            [ nav [ class HorizontalTabNav ]                                    
                [ button                                                        
                    ( maybeCons                                                 
                        editOnClick                                             
                        [ class HorizontalTab                                   
                        , action "/comments/edit" -- fallback for no JS, yeah yeah yeah XSS we handle it.
                        , method "post"                            
                        ]                                                       
                    )                                                           
                    [ text "Edit" ]                                       
                , button                                                        
                    ( maybeCons                                                 
                        previewOnClick                                          
                        [ class HorizontalTab                                   
                        , action "/comments/preview" -- fallback for no JS
                        , method "post"
                        ]                                     
                    )                                                           
                    [ text "Preview" ]                                             
                ]                                                               
            ]                                                                   
        , viewEditorTab                                                         
        ]

Cons

Haskell does not feel the need to implement this. It is really simple function anyone can write if they really need it.

Chadtech commented 7 years ago

Hey that looks pretty cool. Ive been in your situation, but I usually had something a bit clunkier, like a function called buttonAttributes : Bool -> List Attribute.

Chadtech commented 6 years ago

I use maybeCons all the time. Just yesterday that I made a PR over in Maybe.Extra for this function. https://github.com/elm-community/maybe-extra/pull/38

Saying that here for recording keeping in case anyone makes a maybeCons PR on List-Extra