@@ -0,0 +1,132 @@
1+module TodoBench where
2+
3+import String
4+
5+---- MODEL ----
6+
7+-- The full application state of our todo app.
8+type alias Model =
9+ { tasks : List Task
10+ , field : String
11+ , uid : Int
12+ , visibility : String
13+ }
14+
15+
16+type alias Task =
17+ { description : String
18+ , completed : Bool
19+ , editing : Bool
20+ , id : Int
21+ }
22+
23+
24+newTask : String -> Int -> Task
25+newTask desc id =
26+ { description = desc
27+ , completed = False
28+ , editing = False
29+ , id = id
30+ }
31+
32+
33+emptyModel : Model
34+emptyModel =
35+ { tasks = []
36+ , visibility = "All"
37+ , field = ""
38+ , uid = 0
39+ }
40+
41+
42+---- UPDATE ----
43+
44+-- A description of the kinds of actions that can be performed on the model of
45+-- our application. See the following post for more info on this pattern and
46+-- some alternatives: http://elm-lang.org/learn/Architecture.elm
47+type Action
48+ = NoOp
49+ | UpdateField String
50+ | EditingTask Int Bool
51+ | UpdateTask Int String
52+ | Add
53+ | Delete Int
54+ | DeleteComplete
55+ | Check Int Bool
56+ | CheckAll Bool
57+ | ChangeVisibility String
58+
59+
60+-- How we update our Model on a given Action?
61+update : Action -> Model -> Model
62+update action model =
63+ case action of
64+ NoOp -> model
65+
66+ Add ->
67+ { model |
68+ uid <- model.uid + 1,
69+ field <- "",
70+ tasks <-
71+ if String.isEmpty model.field
72+ then model.tasks
73+ else model.tasks ++ [newTask model.field model.uid]
74+ }
75+
76+ UpdateField str ->
77+ { model | field <- str }
78+
79+ EditingTask id isEditing ->
80+ let updateTask t = if t.id == id then { t | editing <- isEditing } else t
81+ in
82+ { model | tasks <- List.map updateTask model.tasks }
83+
84+ UpdateTask id task ->
85+ let updateTask t = if t.id == id then { t | description <- task } else t
86+ in
87+ { model | tasks <- List.map updateTask model.tasks }
88+
89+ Delete id ->
90+ { model | tasks <- List.filter (\t -> t.id /= id) model.tasks }
91+
92+ DeleteComplete ->
93+ { model | tasks <- List.filter (not << .completed) model.tasks }
94+
95+ Check id isCompleted ->
96+ let updateTask t = if t.id == id then { t | completed <- isCompleted } else t
97+ in
98+ { model | tasks <- List.map updateTask model.tasks }
99+
100+ CheckAll isCompleted ->
101+ let updateTask t = { t | completed <- isCompleted }
102+ in
103+ { model | tasks <- List.map updateTask model.tasks }
104+
105+ ChangeVisibility visibility ->
106+ { model | visibility <- visibility }
107+
108+testActions =
109+ List.concat
110+ [ List.concatMap --Add 50 tasks
111+ (\i -> [UpdateField <| "My task " ++ toString i, Add]) [1 .. 50]
112+ , [CheckAll True] --Check them all
113+ , [CheckAll False] --Uncheck them all
114+ , List.concatMap --Alter the text of even numbered tasks
115+ (\i -> [EditingTask i True, UpdateTask i "New Task text", Add] ) <| List.filter (\x -> x % 2 == 0 ) [1 .. 50]
116+ --Check and uncheck some more tasks
117+ , [Check 5 True, Check 7 True, Check 9 True, Check 13 True, Check 17 True, Check 23 True, Check 37 True]
118+ , [Check 7 False, Check 13 False, Check 23 False, Check 37 False]
119+ , [DeleteComplete] --Delete our checked tasks
120+ , [Delete 7, Delete 23] --Delete a few more tasks
121+ , List.concatMap --Add a few more tasks
122+ (\i -> [UpdateField <| "Second batch task " ++ toString i, Add]) [51 .. 80]
123+ , List.map --Check off and delete every other task
124+ (\i -> Check i True ) <| List.filter List.filter (\x -> x % 2 == 0 ) [1 .. 80]
125+ , [DeleteComplete]
126+ , [CheckAll True, DeleteComplete] --Check and delete the remaining tasks
127+ ]
128+
129+
130+evalActions : List Action -> Model
131+evalActions actions =
132+ List.foldr update emptyModel actions