-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathchapter4.idr
52 lines (45 loc) · 1.67 KB
/
chapter4.idr
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
module Main
import Debug.Trace
import Data.Vect;
import Data.String
record DataStore where
constructor MkData
size: Nat
items: Vect size String
data Command = Add String
| Get Integer
| Quit
addToStore : DataStore -> String -> DataStore
addToStore (MkData size items') newitem = MkData _ (addToData items')
where
addToData : Vect old String -> Vect (S old) String
addToData [] = [newitem]
addToData (item :: items') = item :: addToData items'
replMain : DataStore -> String -> Maybe (String, DataStore)
replMain ds text =
let maybeCommand = parseCommand text
in case maybeCommand of
Nothing => pure ("Unknown command", ds)
Just command => processCommand command ds
where
parseCommand : String -> Maybe Command
parseCommand text =
case span (/= ' ') (toLower text) of
("add", args) => pure $ Add (ltrim args)
("get", args) => Get <$> parseInteger args
("quit", _) => pure Quit
_ => Nothing
processCommand : Command -> DataStore -> Maybe (String, DataStore)
processCommand (Add s) ds =
let newStore = addToStore ds s
stringIndex : String = cast (size ds)
in pure ("ID " ++ stringIndex, newStore)
processCommand (Get i) ds =
let maybeValue = do
fin <- integerToFin i (Main.DataStore.size ds)
pure $ Data.Vect.index fin (items ds)
textToShow = fromMaybe "Out of range" maybeValue
in pure (textToShow, ds)
processCommand Quit _ = Nothing
main : IO ()
main = replWith (MkData 0 []) ("\nCommand:") replMain