Skip to content

Instantly share code, notes, and snippets.

@piotrkubisa
Last active June 20, 2019 21:27
Show Gist options
  • Save piotrkubisa/0644d5df824cb29cf8d093dbf435e26c to your computer and use it in GitHub Desktop.
Save piotrkubisa/0644d5df824cb29cf8d093dbf435e26c to your computer and use it in GitHub Desktop.
Elm nesting with recursive types.
module Categories exposing (Model, Msg, init, update, view)
import Html exposing (..)
import Html.Attributes exposing (style)
import Html.Events exposing (onInput, onClick)
type alias Model =
{ entry : String
, children : Children
}
type Children
= Children (List Model)
init : Model
init =
{ entry = "hello world"
, children =
Children
[ { entry = "hello2"
, children =
Children
[ { entry = "hello 3", children = Children [] }
, { entry = "hello 4", children = Children [] }
, { entry = "hello 5", children = Children [] }
]
}
, { entry = "hello 6", children = Children [] }
, { entry = "hello 7", children = Children [] }
]
}
model : Model
model =
init
createTask : String -> Model
createTask entry =
Model entry (Children [])
appendTask : String -> Children -> Children
appendTask entry (Children children) =
Children ((createTask entry) :: children)
-- UPDATE
type Msg
= NoOp
| Write String
| AppendTo Children
update : Msg -> Model -> Model
update msg model =
case msg of
Write newEntry ->
{ model | entry = newEntry }
AppendTo children ->
{ model | children = (appendTask model.entry (Children [])) }
NoOp ->
model
-- VIEW
view : Model -> Html Msg
view model =
div []
[ ul [] [ (viewItem model) ]
]
viewList : Children -> List (Html Msg)
viewList (Children children) =
List.map viewItem children
viewItem : Model -> Html Msg
viewItem item =
li []
[ text item.entry
, (viewForm item)
, ul [] (viewList item.children)
]
viewForm : Model -> Html Msg
viewForm item =
div [ style [] ]
[ input [ style [], onInput Write ] []
, button [ style [], onClick (AppendTo item.children) ] [ text ("append to " ++ (toString item.entry)) ]
]
{
"version": "1.0.0",
"summary": "helpful summary of your project, less than 80 characters",
"repository": "https://github.com/user/project.git",
"license": "BSD3",
"source-directories": [
"."
],
"exposed-modules": [],
"dependencies": {
"elm-lang/core": "4.0.3 <= v < 5.0.0",
"elm-lang/html": "1.1.0 <= v < 2.0.0"
},
"elm-version": "0.17.1 <= v < 0.18.0"
}
module Main exposing (..)
import Categories
import Html exposing (..)
import Html.App as App
-- Main
main : Program Never
main =
App.program
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}
-- Model
type alias Model =
{ categories : Categories.Model
}
init : ( Model, Cmd Msg )
init =
( Model Categories.init, Cmd.none )
-- Subscriptions
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none
-- Update
type Msg
= NoOp
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
NoOp ->
( model, Cmd.none )
view : Model -> Html Msg
view model =
div []
[ App.map (always NoOp) (Categories.view model.categories)
]
@piotrkubisa
Copy link
Author

Revision 5th works. output:

hello world from Main
hello world from Categories

    * hello world
        * hello2
            * hello 3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment