-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProgram.fs
More file actions
68 lines (60 loc) · 1.51 KB
/
Program.fs
File metadata and controls
68 lines (60 loc) · 1.51 KB
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
// Arithmetic Expressions
// This is actually the big step version
type IfExpr = { test: Term; cons: Term; alt: Term }
and Term =
| True
| False
| Zero
| If of IfExpr
| Succ of Term
| Pred of Term
| IsZero of Term
type Res =
| Bool of bool
| Int of int
exception TypeError of string
let rec eval expr =
match expr with
| True -> Bool true
| False -> Bool false
| Zero -> Int 0
| Succ e ->
Int(
match eval e with
| Bool _ -> raise (TypeError "Cannot success a bool value")
| Int i -> i + 1
)
| Pred e ->
Int(
match eval e with
| Bool _ -> raise (TypeError "Cannot predecess a bool value")
| Int 0 -> 0
| Int i -> i - 1
)
| If i ->
match eval i.test with
| Bool true -> eval i.cons
| Bool false -> eval i.alt
| Int _ -> raise (TypeError "Cannot use a int value in if")
| IsZero e ->
Bool(
match eval e with
| Bool _ -> raise (TypeError "Cannot compare a bool value with zero")
| Int 0 -> true
| Int i -> false
)
let print_res term =
try
match eval term with
| Bool b -> printfn "Bool: %b" b
| Int i -> printfn "Int: %i" i
with TypeError str ->
printfn "Error: %s" str
print_res (
If(
{ test = IsZero(Succ(Zero))
cons = Zero
alt = Succ(Pred(Succ(Zero))) }
)
)
print_res (IsZero(False))