-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathPredefined.hs
108 lines (98 loc) · 3.13 KB
/
Predefined.hs
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
{-# LANGUAGE OverloadedStrings #-}
module Predefined (Function(..), functions) where
import Identifier (Identifier)
import Type (TypeScheme(..))
import qualified Type
import Value (Value, RuntimeError(..))
import qualified Value
import Data.Vector ((!))
data Function =
Function
{ name :: Identifier
, typeScheme :: TypeScheme
, function :: Value -> Either RuntimeError Value
}
functions :: [Function]
functions =
[ Function
"head"
(ForAll ["a"]
(Type.Function (Type.List (Type.Var "a")) (Type.Var "a")))
pdHead
, Function
"tail"
(ForAll ["a"]
(Type.Function (Type.List (Type.Var "a")) (Type.List (Type.Var "a"))))
pdTail
, Function
"null"
(ForAll ["a"]
(Type.Function (Type.List (Type.Var "a")) Type.Bool))
pdNull
, Function
"cons"
(ForAll ["a"]
(Type.Function (Type.Var "a") (Type.Function (Type.List (Type.Var "a")) (Type.List (Type.Var "a")))))
pdCons1
, Function
"fst"
(ForAll ["a", "b"]
(Type.Function (Type.Tuple [Type.Var "a", Type.Var "b"]) (Type.Var "a")))
pdFst
, Function
"snd"
(ForAll ["a", "b"]
(Type.Function (Type.Tuple [Type.Var "a", Type.Var "b"]) (Type.Var "b")))
pdSnd
]
pdHead :: Value -> Either RuntimeError Value
pdHead value =
case value of
Value.List elements ->
if null elements then
Left $ RuntimeError "head: the given list is empty"
else
Right $ head elements
_ ->
Left $ RuntimeError "head: the given value is not a list"
pdTail :: Value -> Either RuntimeError Value
pdTail value =
case value of
Value.List elements ->
if null elements then
Left $ RuntimeError "tail: the given list is empty"
else
Right $ Value.List (tail elements)
_ ->
Left $ RuntimeError "tail: the given value is not a list"
pdNull :: Value -> Either RuntimeError Value
pdNull value =
case value of
Value.List elements ->
Right $ Value.Bool (null elements)
_ ->
Left $ RuntimeError "null: the given value is not a list"
pdCons1 :: Value -> Either RuntimeError Value
pdCons1 value =
Right $ Value.NativeFunction "cons" (pdCons2 value)
pdCons2 :: Value -> Value -> Either RuntimeError Value
pdCons2 value1 value2 =
case value2 of
Value.List elements ->
Right $ Value.List (value1:elements)
_ ->
Left $ RuntimeError "cons: the 2nd argument is not a list"
pdFst :: Value -> Either RuntimeError Value
pdFst value =
case value of
Value.Tuple elements ->
Right $ elements ! 0
_ ->
Left $ RuntimeError "fst: the given value is not a tuple"
pdSnd :: Value -> Either RuntimeError Value
pdSnd value =
case value of
Value.Tuple elements ->
Right $ elements ! 1
_ ->
Left $ RuntimeError "snd: the given value is not a tuple"