Elm: part 4 halfway finished. Hello Monads.
[jackhill/mal.git] / elm / step1_read_print.elm
1 port module Main exposing (..)
2
3 import IO exposing (..)
4 import Json.Decode exposing (decodeValue)
5 import Platform exposing (programWithFlags)
6 import Types exposing (MalExpr(..))
7 import Reader exposing (readString)
8 import Printer exposing (printString)
9 import Utils exposing (maybeToList)
10
11
12 main : Program Flags Model Msg
13 main =
14 programWithFlags
15 { init = init
16 , update = update
17 , subscriptions =
18 \model -> input (decodeValue decodeIO >> Input)
19 }
20
21
22 type alias Flags =
23 { args : List String
24 }
25
26
27 type alias Model =
28 { args : List String
29 }
30
31
32 type Msg
33 = Input (Result String IO)
34
35
36 init : Flags -> ( Model, Cmd Msg )
37 init flags =
38 ( flags, readLine prompt )
39
40
41 update : Msg -> Model -> ( Model, Cmd Msg )
42 update msg model =
43 case msg of
44 Input (Ok (LineRead (Just line))) ->
45 case rep line of
46 Just out ->
47 ( model, writeLine out )
48
49 Nothing ->
50 ( model, readLine prompt )
51
52 Input (Ok LineWritten) ->
53 ( model, readLine prompt )
54
55 Input (Ok (LineRead Nothing)) ->
56 ( model, Cmd.none )
57
58 Input (Err msg) ->
59 Debug.crash msg ( model, Cmd.none )
60
61
62 prompt : String
63 prompt =
64 "user> "
65
66
67 {-| read can return three things:
68
69 Ok (Just expr) -> parsed okay
70 Ok Nothing -> empty string (only whitespace and/or comments)
71 Err msg -> parse error
72
73 -}
74 read : String -> Result String (Maybe MalExpr)
75 read =
76 readString
77
78
79 eval : MalExpr -> MalExpr
80 eval ast =
81 ast
82
83
84 print : MalExpr -> String
85 print =
86 printString True
87
88
89 {-| Read-Eval-Print
90 -}
91 rep : String -> Maybe String
92 rep =
93 let
94 formatResult result =
95 case result of
96 Ok optStr ->
97 optStr
98
99 Err msg ->
100 Just msg
101 in
102 readString
103 >> Result.map (Maybe.map (eval >> print))
104 >> formatResult