Last active
March 4, 2016 21:07
-
-
Save lovasoa/70657ac8616f7a7906e1 to your computer and use it in GitHub Desktop.
A little HTML tree editor in Elm, that I did as my first exercise in the language
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Html exposing (Html, Attribute, text, toElement, div, input) | |
import Html.Attributes exposing (..) | |
import Html.Events exposing (on, targetValue) | |
import Signal exposing (Address) | |
import StartApp.Simple as StartApp | |
import Debug | |
type Tree a | |
= Empty | |
| Node a (Tree a) (Tree a) | |
empty : Tree a | |
empty = | |
Empty | |
singleton : a -> Tree a | |
singleton v = | |
Node v Empty Empty | |
insert : comparable -> Tree comparable -> Tree comparable | |
insert x tree = | |
case tree of | |
Empty -> | |
singleton x | |
Node y left right -> | |
if x > y then | |
Node y left (insert x right) | |
else if x < y then | |
Node y (insert x left) right | |
else | |
tree | |
fromList : List comparable -> Tree comparable | |
fromList xs = List.foldl insert empty xs | |
{-- reduce with a reduce and a rereduce functions --} | |
reduceWith : (b -> b -> c) -> (a -> c -> b) -> b -> Tree a -> b | |
reduceWith rereduce reduce init tree = | |
case tree of | |
Empty -> init | |
Node v left right -> | |
let rr = reduceWith rereduce reduce init | |
in reduce v (rereduce (rr left) (rr right)) | |
map : (a -> b) -> Tree a -> Tree b | |
map f = reduceWith (\l r -> (l, r)) (\v (l, r) -> Node (f v) l r) Empty | |
depth : Tree a -> Int | |
depth = reduceWith Basics.max (\_ n -> n+1) 0 | |
flatten : Tree a -> List a | |
flatten = reduceWith (++) (::) [] | |
fold : (a -> b -> b) -> b -> Tree a -> b | |
fold f init tree = List.foldr f init (flatten tree) | |
sum : Tree number -> number | |
sum = fold (+) 0 | |
isElement : a -> Tree a -> Bool | |
isElement k = fold (\v r -> v == k || r) False | |
t1 = fromList [1,2,3] | |
t2 = fromList [2,1,3] | |
main = | |
StartApp.start { model = Empty, view = view', update = update } | |
update: (List Int, String) -> Tree String -> Tree String | |
update (path,val) oldTree = | |
case path of | |
[] -> case oldTree of | |
Empty -> Node val Empty Empty | |
Node _ l r -> Node val l r | |
lr :: rpath -> case oldTree of | |
Empty -> Empty {-- invalid path --} | |
Node vv l r -> if lr == 0 | |
then Node vv (update (rpath, val) l) r | |
else Node vv l (update (rpath, val) r) | |
view : List Int -> Address (List Int, String) -> Tree String -> Html | |
view path adress tree = let full = path==[] in | |
case tree of | |
Empty -> div [myStyle full] | |
[input | |
[ | |
style [("width", "40%")], | |
placeholder "Nouvelle valeur", | |
on "input" targetValue (\s -> Signal.message adress (path,s)) | |
] | |
[] | |
] | |
Node v l r -> div [myStyle full] | |
[ | |
input [ style [("width", "90%")], | |
value v, | |
on "input" targetValue (\s -> Signal.message adress (path,s)) | |
] | |
[], | |
div [] [ | |
view (path++[0]) adress l, | |
view (path++[1]) adress r | |
] | |
] | |
view' : Address (List Int, String) -> Tree String -> Html | |
view' = view [] | |
myStyle full = | |
style | |
[ ("width", if full then "100%" else "45%") | |
, ("border", "1px solid black") | |
, ("display", "inline-block") | |
] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment