├── .gitignore ├── elm-package.json └── src ├── Buttons ├── App.elm ├── Button │ ├── App.elm │ ├── Model.elm │ ├── Update.elm │ └── View.elm └── Count │ ├── App.elm │ ├── Model.elm │ ├── Update.elm │ └── View.elm ├── Checkboxes ├── App.elm ├── Checkbox │ ├── App.elm │ ├── Model.elm │ ├── Update.elm │ └── View.elm └── Styled │ ├── App.elm │ ├── Model.elm │ ├── Update.elm │ └── View.elm ├── Field ├── App.elm ├── Reverse │ ├── App.elm │ ├── Model.elm │ ├── Update.elm │ └── View.elm ├── Style.elm └── Text │ ├── App.elm │ ├── Model.elm │ ├── Update.elm │ └── View.elm ├── Form ├── App.elm ├── Name │ ├── App.elm │ ├── Model.elm │ ├── Update.elm │ └── View.elm ├── Password │ ├── App.elm │ ├── Model.elm │ ├── Update.elm │ └── View.elm └── Validation │ ├── App.elm │ ├── Model.elm │ ├── Update.elm │ └── View.elm ├── Html └── App │ └── Compose.elm ├── LowLevel ├── App.elm ├── Model.elm ├── Update.elm └── View.elm └── RadioButtons ├── App.elm ├── RadioButton ├── App.elm ├── Model.elm ├── Update.elm └── View.elm └── Styled ├── App.elm ├── Model.elm ├── Update.elm └── View.elm /.gitignore: -------------------------------------------------------------------------------- 1 | elm-stuff 2 | build 3 | -------------------------------------------------------------------------------- /elm-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0.0", 3 | "summary": "helpful summary of your project, less than 80 characters", 4 | "repository": "https://github.com/user/project.git", 5 | "license": "BSD3", 6 | "source-directories": [ 7 | "src" 8 | ], 9 | "exposed-modules": [], 10 | "dependencies": { 11 | "elm-community/result-extra": "1.0.0 <= v < 2.0.0", 12 | "elm-lang/core": "4.0.3 <= v < 5.0.0", 13 | "elm-lang/html": "1.1.0 <= v < 2.0.0" 14 | }, 15 | "elm-version": "0.17.1 <= v < 0.18.0" 16 | } 17 | -------------------------------------------------------------------------------- /src/Buttons/App.elm: -------------------------------------------------------------------------------- 1 | module Buttons.App exposing (..) 2 | 3 | import Html.App 4 | 5 | import Buttons.Button.App as Button 6 | import Buttons.Button.Model as Button 7 | import Buttons.Count.App as Count 8 | 9 | import Html.App.Compose exposing (..) 10 | 11 | main : Program Never 12 | main = 13 | decrementButton 14 | |> shareMsg above Count.beginnerProgram 15 | |> shareMsg above incrementButton 16 | |> Html.App.beginnerProgram 17 | 18 | incrementButton : BeginnerProgram (Button.Model (number -> number)) (number -> number) 19 | incrementButton = 20 | Button.beginnerProgram 21 | |> model (Button.model "+" (\x -> x + 1)) 22 | 23 | decrementButton : BeginnerProgram (Button.Model (number -> number)) (number -> number) 24 | decrementButton = 25 | Button.beginnerProgram 26 | |> model (Button.model "-" (\x -> x - 1)) 27 | -------------------------------------------------------------------------------- /src/Buttons/Button/App.elm: -------------------------------------------------------------------------------- 1 | module Buttons.Button.App exposing (..) 2 | 3 | import Html 4 | import Html.App 5 | 6 | import Buttons.Button.Model exposing (..) 7 | import Buttons.Button.Update exposing (..) 8 | import Buttons.Button.View exposing (..) 9 | 10 | beginnerProgram : {model : Model (), update : a -> b -> b, view : Model c -> Html.Html c} 11 | beginnerProgram = 12 | { model = model "" () 13 | , update = update 14 | , view = view 15 | } 16 | 17 | main : Program Never 18 | main = 19 | Html.App.beginnerProgram beginnerProgram 20 | -------------------------------------------------------------------------------- /src/Buttons/Button/Model.elm: -------------------------------------------------------------------------------- 1 | module Buttons.Button.Model exposing (..) 2 | 3 | type alias Model a = 4 | { label : String 5 | , msg : a 6 | } 7 | 8 | model : String -> a -> Model a 9 | model str msg = 10 | {label = str, msg = msg} 11 | -------------------------------------------------------------------------------- /src/Buttons/Button/Update.elm: -------------------------------------------------------------------------------- 1 | module Buttons.Button.Update exposing (..) 2 | 3 | update : a -> b -> b 4 | update _ model = 5 | model 6 | -------------------------------------------------------------------------------- /src/Buttons/Button/View.elm: -------------------------------------------------------------------------------- 1 | module Buttons.Button.View exposing (..) 2 | 3 | import Html exposing (..) 4 | import Html.Events exposing (..) 5 | 6 | import Buttons.Button.Model exposing (Model) 7 | 8 | view : Model a -> Html a 9 | view {label, msg} = 10 | div [] 11 | [ button 12 | [onClick msg] 13 | [text label] 14 | ] 15 | -------------------------------------------------------------------------------- /src/Buttons/Count/App.elm: -------------------------------------------------------------------------------- 1 | module Buttons.Count.App exposing (..) 2 | 3 | import Html 4 | import Html.App 5 | 6 | import Buttons.Count.Model exposing (..) 7 | import Buttons.Count.Update exposing (..) 8 | import Buttons.Count.View exposing (..) 9 | 10 | beginnerProgram : {model : Model, update : Msg Model Model -> Model -> Model, view : Model -> Html.Html a} 11 | beginnerProgram = 12 | { model = model 0 13 | , update = update 14 | , view = view 15 | } 16 | 17 | main : Program Never 18 | main = 19 | Html.App.beginnerProgram beginnerProgram 20 | -------------------------------------------------------------------------------- /src/Buttons/Count/Model.elm: -------------------------------------------------------------------------------- 1 | module Buttons.Count.Model exposing (..) 2 | 3 | type alias Model = 4 | Int 5 | 6 | model : Int -> Model 7 | model x = 8 | x 9 | -------------------------------------------------------------------------------- /src/Buttons/Count/Update.elm: -------------------------------------------------------------------------------- 1 | module Buttons.Count.Update exposing (..) 2 | 3 | type alias Msg a b = 4 | a -> b 5 | 6 | update : (a -> b) -> a -> b 7 | update msg model = 8 | msg model 9 | -------------------------------------------------------------------------------- /src/Buttons/Count/View.elm: -------------------------------------------------------------------------------- 1 | module Buttons.Count.View exposing (..) 2 | 3 | import Html exposing (..) 4 | 5 | import Buttons.Count.Model exposing (Model) 6 | 7 | view : Model -> Html.Html a 8 | view model = 9 | Html.div [] 10 | [Html.text (toString model)] 11 | -------------------------------------------------------------------------------- /src/Checkboxes/App.elm: -------------------------------------------------------------------------------- 1 | module Checkboxes.App exposing (..) 2 | 3 | import Html.App exposing (beginnerProgram) 4 | 5 | import Result.Extra exposing (mapBoth) 6 | 7 | import Html.App.Compose exposing (..) 8 | 9 | import Checkboxes.Checkbox.App as Checkbox 10 | import Checkboxes.Checkbox.Model as Checkbox 11 | import Checkboxes.Checkbox.Update as Checkbox 12 | import Checkboxes.Checkbox.View as Checkbox 13 | import Checkboxes.Styled.App as Styled 14 | import Checkboxes.Styled.Model as Styled 15 | import Checkboxes.Styled.Update as Styled 16 | 17 | main : Program Never 18 | main = 19 | styled 20 | |> shareMsg above checkboxes 21 | |> Html.App.beginnerProgram 22 | 23 | checkboxes 24 | : BeginnerProgram 25 | ((Checkbox.Model, Checkbox.Model), Checkbox.Model) 26 | (Result 27 | (Result (Checkbox.Msg String) (Checkbox.Msg String)) 28 | (Checkbox.Msg String)) 29 | checkboxes = 30 | let 31 | checkboxProgram = 32 | Checkbox.beginnerProgram 33 | in 34 | { checkboxProgram 35 | | view = Checkbox.view "color" "red" 36 | } 37 | |> above 38 | { checkboxProgram 39 | | view = Checkbox.view "text-decoration" "underline" 40 | } 41 | |> above 42 | { checkboxProgram 43 | | view = Checkbox.view "font-weight" "bold" 44 | } 45 | 46 | styled 47 | : BeginnerProgram 48 | Styled.Model 49 | (Result (Result Styled.Msg Styled.Msg) Styled.Msg) 50 | styled = 51 | let 52 | styledProgram = 53 | Styled.beginnerProgram 54 | in 55 | { styledProgram 56 | | update = Styled.update << mapBoth (mapBoth identity identity) identity 57 | } 58 | -------------------------------------------------------------------------------- /src/Checkboxes/Checkbox/App.elm: -------------------------------------------------------------------------------- 1 | module Checkboxes.Checkbox.App exposing (..) 2 | 3 | import Html.App 4 | 5 | import Html.App.Compose exposing (BeginnerProgram) 6 | 7 | import Checkboxes.Checkbox.Model exposing (..) 8 | import Checkboxes.Checkbox.Update exposing (..) 9 | import Checkboxes.Checkbox.View exposing (..) 10 | 11 | beginnerProgram : BeginnerProgram Model (Msg String) 12 | beginnerProgram = 13 | {model = model False, update = update, view = view "" ""} 14 | 15 | main : Program Never 16 | main = 17 | Html.App.beginnerProgram beginnerProgram 18 | -------------------------------------------------------------------------------- /src/Checkboxes/Checkbox/Model.elm: -------------------------------------------------------------------------------- 1 | module Checkboxes.Checkbox.Model exposing (..) 2 | 3 | type alias Model = 4 | Bool 5 | 6 | model : Bool -> Model 7 | model bool = 8 | bool 9 | -------------------------------------------------------------------------------- /src/Checkboxes/Checkbox/Update.elm: -------------------------------------------------------------------------------- 1 | module Checkboxes.Checkbox.Update exposing (..) 2 | 3 | import Checkboxes.Checkbox.Model exposing (..) 4 | 5 | type alias Msg a = 6 | (a, String) 7 | 8 | update : a -> Model -> Model 9 | update msg model = 10 | not model 11 | -------------------------------------------------------------------------------- /src/Checkboxes/Checkbox/View.elm: -------------------------------------------------------------------------------- 1 | module Checkboxes.Checkbox.View exposing (..) 2 | 3 | import Html exposing (..) 4 | import Html.Attributes exposing (checked, type') 5 | import Html.Events exposing (onCheck) 6 | 7 | import Checkboxes.Checkbox.Model exposing (..) 8 | import Checkboxes.Checkbox.Update exposing (..) 9 | 10 | view : a -> String -> Model -> Html (Msg a) 11 | view attribute value model = 12 | label [] 13 | [ input 14 | [ type' "checkbox" 15 | , checked model 16 | , onCheck (interpret attribute value) 17 | ] 18 | [] 19 | , text value 20 | ] 21 | 22 | interpret : a -> String -> Model -> Msg a 23 | interpret attribute value checked = 24 | (attribute, if checked then value else "") 25 | -------------------------------------------------------------------------------- /src/Checkboxes/Styled/App.elm: -------------------------------------------------------------------------------- 1 | module Checkboxes.Styled.App exposing (..) 2 | 3 | import Html exposing (Html) 4 | import Html.App 5 | 6 | import Checkboxes.Styled.Model exposing (..) 7 | import Checkboxes.Styled.Update exposing (..) 8 | import Checkboxes.Styled.View exposing (..) 9 | 10 | beginnerProgram : {model : Model, update : Msg -> Model -> Model , view : Model -> Html msg} 11 | beginnerProgram = 12 | {model = model, update = update, view = view} 13 | 14 | main : Program Never 15 | main = 16 | Html.App.beginnerProgram beginnerProgram 17 | -------------------------------------------------------------------------------- /src/Checkboxes/Styled/Model.elm: -------------------------------------------------------------------------------- 1 | module Checkboxes.Styled.Model exposing (..) 2 | 3 | import Dict exposing (..) 4 | 5 | type alias Model = 6 | Dict String String 7 | 8 | model : Dict String String 9 | model = 10 | empty 11 | -------------------------------------------------------------------------------- /src/Checkboxes/Styled/Update.elm: -------------------------------------------------------------------------------- 1 | module Checkboxes.Styled.Update exposing (..) 2 | 3 | import Dict exposing (..) 4 | 5 | import Checkboxes.Styled.Model exposing (..) 6 | 7 | type alias Msg = 8 | (String, String) 9 | 10 | update : Msg -> Model -> Model 11 | update msg model = 12 | uncurry insert msg model 13 | -------------------------------------------------------------------------------- /src/Checkboxes/Styled/View.elm: -------------------------------------------------------------------------------- 1 | module Checkboxes.Styled.View exposing (..) 2 | 3 | import Dict exposing (..) 4 | import Html exposing (..) 5 | import Html.Attributes exposing (style) 6 | 7 | import Checkboxes.Styled.Model exposing (..) 8 | 9 | view : Model -> Html a 10 | view model = 11 | span [style (toList model)] [text "Hello, how are you?!"] 12 | -------------------------------------------------------------------------------- /src/Field/App.elm: -------------------------------------------------------------------------------- 1 | module Field.App exposing (..) 2 | 3 | import Html.App 4 | 5 | import Html.App.Compose exposing (..) 6 | 7 | import Field.Reverse.App as Reverse 8 | import Field.Text.App as Text 9 | 10 | main : Program Never 11 | main = 12 | Reverse.beginnerProgram 13 | |> shareMsg above Text.beginnerProgram 14 | |> Html.App.beginnerProgram 15 | -------------------------------------------------------------------------------- /src/Field/Reverse/App.elm: -------------------------------------------------------------------------------- 1 | module Field.Reverse.App exposing (..) 2 | 3 | import Html.App 4 | 5 | import Field.Reverse.Model exposing (..) 6 | import Field.Reverse.Update exposing (..) 7 | import Field.Reverse.View exposing (..) 8 | 9 | import Html.App.Compose exposing (BeginnerProgram) 10 | 11 | beginnerProgram : BeginnerProgram Model Msg 12 | beginnerProgram = 13 | {model = model, update = update, view = always view} 14 | 15 | main : Program Never 16 | main = 17 | Html.App.beginnerProgram beginnerProgram 18 | -------------------------------------------------------------------------------- /src/Field/Reverse/Model.elm: -------------------------------------------------------------------------------- 1 | module Field.Reverse.Model exposing (..) 2 | 3 | type alias Model = 4 | () 5 | 6 | model : Model 7 | model = 8 | () 9 | -------------------------------------------------------------------------------- /src/Field/Reverse/Update.elm: -------------------------------------------------------------------------------- 1 | module Field.Reverse.Update exposing (..) 2 | 3 | type alias Msg = 4 | String 5 | 6 | update : a -> b -> b 7 | update msg model = 8 | model 9 | -------------------------------------------------------------------------------- /src/Field/Reverse/View.elm: -------------------------------------------------------------------------------- 1 | module Field.Reverse.View exposing (..) 2 | 3 | import Html exposing (..) 4 | import Html.Attributes exposing (..) 5 | import Html.Events exposing (..) 6 | import String exposing (..) 7 | 8 | import Field.Reverse.Update exposing (..) 9 | import Field.Style exposing (..) 10 | 11 | view : Html Msg 12 | view = 13 | input [ placeholder "Text to reverse", onInput reverse, myStyle ] [] 14 | -------------------------------------------------------------------------------- /src/Field/Style.elm: -------------------------------------------------------------------------------- 1 | module Field.Style exposing (..) 2 | 3 | import Html exposing (Attribute) 4 | import Html.Attributes exposing (style) 5 | 6 | myStyle : Attribute a 7 | myStyle = 8 | style 9 | [ ("width", "100%") 10 | , ("height", "40px") 11 | , ("padding", "10px 0") 12 | , ("font-size", "2em") 13 | , ("text-align", "center") 14 | ] 15 | -------------------------------------------------------------------------------- /src/Field/Text/App.elm: -------------------------------------------------------------------------------- 1 | module Field.Text.App exposing (..) 2 | 3 | import Html.App 4 | 5 | import Field.Text.Model exposing (..) 6 | import Field.Text.Update exposing (..) 7 | import Field.Text.View exposing (..) 8 | 9 | import Html.App.Compose exposing (BeginnerProgram) 10 | 11 | beginnerProgram : BeginnerProgram Model Model 12 | beginnerProgram = 13 | {model = model "", update = update, view = view} 14 | 15 | main : Program Never 16 | main = 17 | Html.App.beginnerProgram beginnerProgram 18 | -------------------------------------------------------------------------------- /src/Field/Text/Model.elm: -------------------------------------------------------------------------------- 1 | module Field.Text.Model exposing (..) 2 | 3 | type alias Model = 4 | String 5 | 6 | model : String -> Model 7 | model str = 8 | str 9 | -------------------------------------------------------------------------------- /src/Field/Text/Update.elm: -------------------------------------------------------------------------------- 1 | module Field.Text.Update exposing (..) 2 | 3 | update : a -> b -> a 4 | update newContent oldContent = 5 | newContent 6 | -------------------------------------------------------------------------------- /src/Field/Text/View.elm: -------------------------------------------------------------------------------- 1 | module Field.Text.View exposing (..) 2 | 3 | import Html exposing (..) 4 | 5 | import Field.Text.Model exposing (..) 6 | import Field.Style exposing (..) 7 | 8 | view : Model -> Html s 9 | view content = 10 | div [ myStyle ] [ text content ] 11 | -------------------------------------------------------------------------------- /src/Form/App.elm: -------------------------------------------------------------------------------- 1 | module Form.App exposing (..) 2 | 3 | import Html.App as App 4 | import Html.App.Compose as Compose exposing (..) 5 | 6 | import Form.Name.App as Name 7 | import Form.Password.App as Password 8 | import Form.Password.Model as Password 9 | import Form.Password.Update as Password 10 | import Form.Password.View as Password 11 | import Form.Validation.App as Validation 12 | 13 | main : Program Never 14 | main = 15 | Name.beginnerProgram 16 | |> before passwords 17 | |> usingOk (shareMsg above) Validation.beginnerProgram 18 | |> App.beginnerProgram 19 | 20 | passwords : BeginnerProgram (Password.Model String, Password.Model String) (Result Password.Msg Password.Msg) 21 | passwords = 22 | (Password.beginnerProgram |> view (Password.view "Password")) 23 | |> before 24 | (Password.beginnerProgram |> view (Password.view "Re-enter Password")) 25 | -------------------------------------------------------------------------------- /src/Form/Name/App.elm: -------------------------------------------------------------------------------- 1 | module Form.Name.App exposing (..) 2 | 3 | import Html.App 4 | 5 | import Form.Name.Model exposing (..) 6 | import Form.Name.Update exposing (..) 7 | import Form.Name.View exposing (..) 8 | 9 | import Html.App.Compose as Compose exposing (BeginnerProgram) 10 | 11 | beginnerProgram : BeginnerProgram Model String 12 | beginnerProgram = 13 | {model = model "", update = update, view = view} 14 | 15 | main : Program Never 16 | main = 17 | Html.App.beginnerProgram beginnerProgram 18 | -------------------------------------------------------------------------------- /src/Form/Name/Model.elm: -------------------------------------------------------------------------------- 1 | module Form.Name.Model exposing (..) 2 | 3 | type alias Model = 4 | String 5 | 6 | model : String -> Model 7 | model str = 8 | str 9 | -------------------------------------------------------------------------------- /src/Form/Name/Update.elm: -------------------------------------------------------------------------------- 1 | module Form.Name.Update exposing (..) 2 | 3 | type alias Msg = 4 | String 5 | 6 | update : a -> b -> a 7 | update str model = 8 | str 9 | -------------------------------------------------------------------------------- /src/Form/Name/View.elm: -------------------------------------------------------------------------------- 1 | module Form.Name.View exposing (..) 2 | 3 | import Html exposing (..) 4 | import Html.Attributes exposing (..) 5 | import Html.Events exposing (..) 6 | 7 | import Form.Name.Model exposing (..) 8 | import Form.Name.Update exposing (..) 9 | 10 | view : Model -> Html Msg 11 | view model = 12 | input [ type' "text", placeholder "Name", onInput identity ] [] 13 | -------------------------------------------------------------------------------- /src/Form/Password/App.elm: -------------------------------------------------------------------------------- 1 | module Form.Password.App exposing (..) 2 | 3 | import Html.App 4 | 5 | import Form.Password.Model exposing (..) 6 | import Form.Password.Update exposing (..) 7 | import Form.Password.View exposing (..) 8 | 9 | import Html.App.Compose as Compose exposing (BeginnerProgram) 10 | 11 | beginnerProgram : BeginnerProgram (Model String) String 12 | beginnerProgram = 13 | {model = model identity, update = update, view = view ""} 14 | 15 | main : Program Never 16 | main = 17 | Html.App.beginnerProgram beginnerProgram 18 | -------------------------------------------------------------------------------- /src/Form/Password/Model.elm: -------------------------------------------------------------------------------- 1 | module Form.Password.Model exposing (..) 2 | 3 | type alias Model a = 4 | String -> a 5 | 6 | model : (String -> a) -> Model a 7 | model f = 8 | f 9 | -------------------------------------------------------------------------------- /src/Form/Password/Update.elm: -------------------------------------------------------------------------------- 1 | module Form.Password.Update exposing (..) 2 | 3 | type alias Msg = 4 | String 5 | 6 | update : a -> b -> b 7 | update msg model = 8 | model 9 | -------------------------------------------------------------------------------- /src/Form/Password/View.elm: -------------------------------------------------------------------------------- 1 | module Form.Password.View exposing (..) 2 | 3 | import Html exposing (..) 4 | import Html.Attributes exposing (..) 5 | import Html.Events exposing (onInput) 6 | 7 | import Form.Password.Model exposing (..) 8 | 9 | view : String -> Model a -> Html a 10 | view place event = 11 | input [ type' "password", placeholder place, onInput event ] [] 12 | -------------------------------------------------------------------------------- /src/Form/Validation/App.elm: -------------------------------------------------------------------------------- 1 | module Form.Validation.App exposing (..) 2 | 3 | import Html exposing (..) 4 | import Html.App 5 | 6 | import Form.Validation.Model exposing (..) 7 | import Form.Validation.Update exposing (..) 8 | import Form.Validation.View exposing (..) 9 | 10 | beginnerProgram : {model : Model String String, update : Msg a a -> Model a a -> Model a a, view : Model b c -> Html.Html d} 11 | beginnerProgram = 12 | {model = model "" "", update = update, view = view} 13 | 14 | main : Program Never 15 | main = 16 | Html.App.beginnerProgram beginnerProgram 17 | -------------------------------------------------------------------------------- /src/Form/Validation/Model.elm: -------------------------------------------------------------------------------- 1 | module Form.Validation.Model exposing (..) 2 | 3 | type alias Model password passwordAgain = 4 | { color : String 5 | , message : String 6 | , password : password 7 | , passwordAgain : passwordAgain 8 | } 9 | 10 | model : a -> a -> Model a a 11 | model password passwordAgain = 12 | if password == passwordAgain then 13 | { color = "green" 14 | , message = "OK" 15 | , password = password 16 | , passwordAgain = passwordAgain 17 | } 18 | else 19 | { color = "red" 20 | , message = "Passwords do not match!" 21 | , password = password 22 | , passwordAgain = passwordAgain 23 | } 24 | 25 | -------------------------------------------------------------------------------- /src/Form/Validation/Update.elm: -------------------------------------------------------------------------------- 1 | module Form.Validation.Update exposing (..) 2 | 3 | import Form.Validation.Model exposing (..) 4 | 5 | type alias Msg a b = 6 | Result a b 7 | 8 | update : Msg a a -> Model a a -> Model a a 9 | update msg {password, passwordAgain} = 10 | case msg of 11 | Err newPassword -> 12 | model newPassword passwordAgain 13 | Ok newPassword -> 14 | model password newPassword 15 | -------------------------------------------------------------------------------- /src/Form/Validation/View.elm: -------------------------------------------------------------------------------- 1 | module Form.Validation.View exposing (..) 2 | 3 | import Html exposing (..) 4 | import Html.Attributes exposing (..) 5 | 6 | import Form.Validation.Model exposing (..) 7 | 8 | view : Model a b -> Html c 9 | view {color, message} = 10 | div [ style [("color", color)] ] [ text message ] 11 | -------------------------------------------------------------------------------- /src/Html/App/Compose.elm: -------------------------------------------------------------------------------- 1 | module Html.App.Compose exposing (..) 2 | 3 | import Html 4 | import Html.App 5 | import Html.Attributes as Attributes 6 | 7 | import Result.Extra exposing (mapBoth) 8 | 9 | type alias BeginnerProgram model msg = 10 | { model : model 11 | , update : msg -> model -> model 12 | , view : model -> Html.Html msg 13 | } 14 | 15 | type alias Composition model1 msg1 model2 msg2 model msg = 16 | BeginnerProgram model1 msg1 -> BeginnerProgram model2 msg2 -> BeginnerProgram model msg 17 | 18 | model : b -> {r | model : a} -> {r | model : b} 19 | model x = 20 | modelMap (always x) 21 | 22 | modelMap : (a -> b) -> {r | model : a} -> {r | model : b} 23 | modelMap f record = 24 | {record | model = f record.model} 25 | 26 | update : b -> {r | update : a} -> {r | update : b} 27 | update x = 28 | updateMap (always x) 29 | 30 | updateMap : (a -> b) -> {r | update : a} -> {r | update : b} 31 | updateMap f record = 32 | {record | update = f record.update} 33 | 34 | view : b -> {r | view : a} -> {r | view : b} 35 | view x = 36 | viewMap (always x) 37 | 38 | viewMap : (a -> b) -> {r | view : a} -> {r | view : b} 39 | viewMap f record = 40 | {record | view = f record.view} 41 | 42 | below : Composition a b c d (a, c) (Result b d) 43 | below first second = 44 | { model = (first.model, second.model) 45 | , view = \(firstModel, secondModel) -> 46 | Html.div 47 | [ Attributes.style 48 | [("display", "flex"), ("flex-direction", "column")] 49 | ] 50 | [ Html.App.map Err (first.view firstModel) 51 | , Html.App.map Ok (second.view secondModel) 52 | ] 53 | , update = \firstRightMsg (firstModel, secondModel)-> 54 | case firstRightMsg of 55 | Err msg -> 56 | (first.update msg firstModel, secondModel) 57 | Ok msg -> 58 | (firstModel, second.update msg secondModel) 59 | } 60 | 61 | above : Composition c d a b (a, c) (Result b d) 62 | above second first = 63 | below first second 64 | 65 | after : Composition a b c d (a, c) (Result b d) 66 | after left right = 67 | let 68 | prog = 69 | below left right 70 | in 71 | { prog 72 | | view = \(leftModel, rightModel) -> 73 | Html.div [Attributes.style [("display", "flex")]] 74 | [ Html.App.map Err (left.view leftModel) 75 | , Html.App.map Ok (right.view rightModel) 76 | ] 77 | } 78 | 79 | before : Composition c d a b (a, c) (Result b d) 80 | before right left = 81 | after left right 82 | 83 | shareMsg 84 | : Composition c b a b (a, c) (Result b b) 85 | -> Composition c b a b (a, c) b 86 | shareMsg composition second first = 87 | composition second first 88 | |> update (\msg (firstModel, secondModel) -> 89 | (first.update msg firstModel, second.update msg secondModel) 90 | ) 91 | |> viewMap ((<<) (Html.App.map (mapBoth identity identity))) 92 | 93 | shareMsg' 94 | : Composition a b c b (a, c) (Result b b) 95 | -> Composition a b c b (a, c) b 96 | shareMsg' composition first second = 97 | shareMsg (flip composition) second first 98 | 99 | usingErr 100 | : Composition a (Result b c) d (Result b c) e (Result b c) 101 | -> Composition a b d (Result b c) e (Result b c) 102 | usingErr composition program = 103 | program 104 | |> viewMap ((<<) (Html.App.map Err)) 105 | |> updateMap (flip mapBoth (always identity)) 106 | |> composition 107 | 108 | usingOk 109 | : Composition a (Result b c) d (Result b c) e (Result b c) 110 | -> Composition a c d (Result b c) e (Result b c) 111 | usingOk composition program = 112 | program 113 | |> viewMap ((<<) (Html.App.map Ok)) 114 | |> updateMap (mapBoth (always identity)) 115 | |> composition 116 | -------------------------------------------------------------------------------- /src/LowLevel/App.elm: -------------------------------------------------------------------------------- 1 | module LowLevel.App exposing (..) 2 | 3 | import Html.App 4 | 5 | import LowLevel.Model exposing (..) 6 | import LowLevel.Update exposing (..) 7 | import LowLevel.View exposing (..) 8 | 9 | main : Program Never 10 | main = 11 | Html.App.beginnerProgram 12 | { model = (model "-" 0 "+") 13 | , update = update 14 | , view = view 15 | } 16 | -------------------------------------------------------------------------------- /src/LowLevel/Model.elm: -------------------------------------------------------------------------------- 1 | module LowLevel.Model exposing (..) 2 | 3 | import Buttons.Button.Model as Button 4 | 5 | import Buttons.Count.Model as Count 6 | 7 | type alias Model = 8 | { firstButton : Button.Model (Int -> Int) 9 | , count : Count.Model 10 | , secondButton : Button.Model (Int -> Int) 11 | } 12 | 13 | model : String -> Int -> String -> Model 14 | model first count second = 15 | { firstButton = Button.model first (\x -> x - 1) 16 | , count = Count.model count 17 | , secondButton = Button.model second (\x -> x + 1) 18 | } 19 | -------------------------------------------------------------------------------- /src/LowLevel/Update.elm: -------------------------------------------------------------------------------- 1 | module LowLevel.Update exposing (..) 2 | 3 | import LowLevel.Model exposing (Model) 4 | 5 | import Buttons.Button.Update as Button 6 | import Buttons.Count.Model as Count 7 | import Buttons.Count.Update as Count 8 | 9 | type alias Msg = 10 | Count.Msg Count.Model Count.Model 11 | 12 | update : Msg -> Model -> Model 13 | update msg model = 14 | { model 15 | | firstButton = Button.update msg model.firstButton 16 | , count = Count.update msg model.count 17 | , secondButton = Button.update msg model.secondButton 18 | } 19 | -------------------------------------------------------------------------------- /src/LowLevel/View.elm: -------------------------------------------------------------------------------- 1 | module LowLevel.View exposing (..) 2 | 3 | import Html 4 | 5 | import LowLevel.Model exposing (Model) 6 | import LowLevel.Update exposing (Msg) 7 | 8 | import Buttons.Button.View as Button 9 | import Buttons.Count.View as Count 10 | 11 | view : Model -> Html.Html Msg 12 | view model = 13 | Html.div 14 | [] 15 | [ (Button.view << .firstButton) model 16 | , (Count.view << .count) model 17 | , (Button.view << .secondButton) model 18 | ] 19 | -------------------------------------------------------------------------------- /src/RadioButtons/App.elm: -------------------------------------------------------------------------------- 1 | module RadioButtons.App exposing (..) 2 | 3 | import Html.App exposing (beginnerProgram) 4 | 5 | import Result.Extra exposing (mapBoth) 6 | 7 | import Html.App.Compose exposing (..) 8 | 9 | import RadioButtons.RadioButton.App as RadioButton 10 | import RadioButtons.RadioButton.Model as RadioButton 11 | import RadioButtons.RadioButton.Update as RadioButton 12 | import RadioButtons.RadioButton.View as RadioButton 13 | import RadioButtons.Styled.App as Styled 14 | import RadioButtons.Styled.Model as Styled 15 | import RadioButtons.Styled.Update as Styled 16 | 17 | main : Program Never 18 | main = 19 | styled 20 | |> shareMsg above radioButtons 21 | |> Html.App.beginnerProgram 22 | 23 | radioButtons 24 | : BeginnerProgram 25 | ((RadioButton.Model, RadioButton.Model), RadioButton.Model) 26 | (Result 27 | (Result (RadioButton.Msg String String) (RadioButton.Msg String String)) 28 | (RadioButton.Msg String String)) 29 | radioButtons = 30 | let 31 | radioProgram = 32 | RadioButton.beginnerProgram 33 | in 34 | { radioProgram 35 | | view = RadioButton.view "color" "red" 36 | , model = RadioButton.model "style" 37 | } 38 | |> above 39 | { radioProgram 40 | | view = RadioButton.view "text-decoration" "underline" 41 | , model = RadioButton.model "style" 42 | } 43 | |> above 44 | { radioProgram 45 | | view = RadioButton.view "font-weight" "bold" 46 | , model = RadioButton.model "style" 47 | } 48 | 49 | styled 50 | : BeginnerProgram 51 | Styled.Model 52 | (Result (Result Styled.Msg Styled.Msg) Styled.Msg) 53 | styled = 54 | let 55 | styledProgram = 56 | Styled.beginnerProgram 57 | in 58 | { styledProgram 59 | | update = Styled.update << mapBoth (mapBoth identity identity) identity 60 | } 61 | -------------------------------------------------------------------------------- /src/RadioButtons/RadioButton/App.elm: -------------------------------------------------------------------------------- 1 | module RadioButtons.RadioButton.App exposing (..) 2 | 3 | import Html.App 4 | 5 | import Html.App.Compose exposing (BeginnerProgram) 6 | 7 | import RadioButtons.RadioButton.Model exposing (..) 8 | import RadioButtons.RadioButton.Update exposing (..) 9 | import RadioButtons.RadioButton.View exposing (..) 10 | 11 | beginnerProgram : BeginnerProgram Model (Msg String String) 12 | beginnerProgram = 13 | {model = model "", update = update, view = view "" ""} 14 | 15 | main : Program Never 16 | main = 17 | Html.App.beginnerProgram beginnerProgram 18 | -------------------------------------------------------------------------------- /src/RadioButtons/RadioButton/Model.elm: -------------------------------------------------------------------------------- 1 | module RadioButtons.RadioButton.Model exposing (..) 2 | 3 | type alias Model = 4 | String 5 | 6 | model : String -> Model 7 | model group = 8 | group 9 | -------------------------------------------------------------------------------- /src/RadioButtons/RadioButton/Update.elm: -------------------------------------------------------------------------------- 1 | module RadioButtons.RadioButton.Update exposing (..) 2 | 3 | type alias Msg a b = 4 | (a, b) 5 | 6 | update : a -> b -> b 7 | update msg model = 8 | model 9 | -------------------------------------------------------------------------------- /src/RadioButtons/RadioButton/View.elm: -------------------------------------------------------------------------------- 1 | module RadioButtons.RadioButton.View exposing (..) 2 | 3 | import Html exposing (..) 4 | import Html.Attributes exposing (checked, name, type') 5 | import Html.Events exposing (on, targetChecked) 6 | 7 | import Json.Decode exposing (..) 8 | 9 | import RadioButtons.RadioButton.Model exposing (..) 10 | import RadioButtons.RadioButton.Update exposing (..) 11 | 12 | view : a -> String -> Model -> Html (Msg a String) 13 | view attribute value model = 14 | label [] 15 | [ input 16 | [ type' "radio" 17 | , name model 18 | , on "change" (interpret attribute value) 19 | ] 20 | [] 21 | , text value 22 | ] 23 | 24 | interpret : a -> b -> Decoder (Msg a b) 25 | interpret attribute value = 26 | targetChecked `andThen` \b -> 27 | if b then 28 | succeed (attribute, value) 29 | else 30 | fail "" 31 | -------------------------------------------------------------------------------- /src/RadioButtons/Styled/App.elm: -------------------------------------------------------------------------------- 1 | module RadioButtons.Styled.App exposing (..) 2 | 3 | import Html exposing (Html) 4 | import Html.App 5 | 6 | import RadioButtons.Styled.Model exposing (..) 7 | import RadioButtons.Styled.Update exposing (..) 8 | import RadioButtons.Styled.View exposing (..) 9 | 10 | beginnerProgram : {model : Model, update : Msg -> Model -> Msg , view : Model -> Html msg} 11 | beginnerProgram = 12 | {model = model ("", ""), update = update, view = view} 13 | 14 | main : Program Never 15 | main = 16 | Html.App.beginnerProgram beginnerProgram 17 | -------------------------------------------------------------------------------- /src/RadioButtons/Styled/Model.elm: -------------------------------------------------------------------------------- 1 | module RadioButtons.Styled.Model exposing (..) 2 | 3 | type alias Model = 4 | (String, String) 5 | 6 | model : (String, String) -> Model 7 | model = 8 | identity 9 | -------------------------------------------------------------------------------- /src/RadioButtons/Styled/Update.elm: -------------------------------------------------------------------------------- 1 | module RadioButtons.Styled.Update exposing (..) 2 | 3 | type alias Msg = 4 | (String, String) 5 | 6 | update : a -> b -> a 7 | update msg model = 8 | msg 9 | -------------------------------------------------------------------------------- /src/RadioButtons/Styled/View.elm: -------------------------------------------------------------------------------- 1 | module RadioButtons.Styled.View exposing (..) 2 | 3 | import Html exposing (..) 4 | import Html.Attributes exposing (style) 5 | 6 | import RadioButtons.Styled.Model exposing (..) 7 | 8 | view : Model -> Html a 9 | view model = 10 | span [style [model]] [text "Hello, how are you?!"] 11 | --------------------------------------------------------------------------------