回答編集履歴

3

eval の型について追記

2021/06/03 08:01

投稿

ozwk
ozwk

スコア13528

test CHANGED
@@ -51,6 +51,26 @@
51
51
  その次の返り値 `assoc x list`の型は`'a option`と何かしらのオプション型なので
52
52
 
53
53
  型が全然合ってません。
54
+
55
+
56
+
57
+ 問題文を見ると、
58
+
59
+
60
+
61
+ > eval [("x",4);("y",3)] (Mul(Mul(Var "x", Var "y"),Add(Var "x",Num 3)));;
62
+
63
+ >
64
+
65
+ > : int = Some 84
66
+
67
+
68
+
69
+ なのですから `eval`の返り値は`int option`とすべきですね。
70
+
71
+ つまり`|Num n -> n`の時点でもう型が違います。
72
+
73
+
54
74
 
55
75
 
56
76
 

2

コード追加

2021/06/03 08:01

投稿

ozwk
ozwk

スコア13528

test CHANGED
@@ -57,3 +57,115 @@
57
57
 
58
58
 
59
59
  とりあえず(全部消してイチから)全部の関数に型を明示して書いてはどうでしょう。
60
+
61
+
62
+
63
+
64
+
65
+ ---
66
+
67
+
68
+
69
+ 文法が似ているF#で書いてみました
70
+
71
+
72
+
73
+ ```F#
74
+
75
+ open System
76
+
77
+
78
+
79
+
80
+
81
+ type Exp =
82
+
83
+ | Num of int
84
+
85
+ | Var of string
86
+
87
+ | Add of Exp * Exp
88
+
89
+ | Mul of Exp * Exp
90
+
91
+
92
+
93
+
94
+
95
+ // let hoge = Mul(Num 3, Var "x") // OK
96
+
97
+
98
+
99
+ type VarValuePair = string * int
100
+
101
+
102
+
103
+
104
+
105
+ let rec assoc (name : string) (pairs : VarValuePair list) : int option =
106
+
107
+ match pairs with
108
+
109
+ | [] -> None
110
+
111
+ | (var, value)::t ->
112
+
113
+ if var = name then Some value
114
+
115
+ else assoc name t
116
+
117
+
118
+
119
+ let rec eval (pairs : VarValuePair list) (exp : Exp): int option =
120
+
121
+ match exp with
122
+
123
+ | Num x -> Some x
124
+
125
+ | Var var -> assoc var pairs
126
+
127
+ | Add (x, y) ->
128
+
129
+ let x = (eval pairs x)
130
+
131
+ let y = (eval pairs y)
132
+
133
+ match (x, y) with
134
+
135
+ | (Some x, Some y) -> Some (x+y)
136
+
137
+ | _ -> None
138
+
139
+ | Mul (x, y) ->
140
+
141
+ let x = (eval pairs x)
142
+
143
+ let y = (eval pairs y)
144
+
145
+ match (x, y) with
146
+
147
+ | (Some x, Some y) -> Some (x*y)
148
+
149
+ | _ -> None
150
+
151
+
152
+
153
+
154
+
155
+ [<EntryPoint>]
156
+
157
+ let main argv =
158
+
159
+
160
+
161
+ let result = eval [("x",4); ("y",3)] (Mul(Mul(Var "x", Var "y"),Add(Var "x",Num 3)))
162
+
163
+ printfn "%A" result
164
+
165
+ 0 // return an integer exit code
166
+
167
+
168
+
169
+
170
+
171
+ ```

1

追記

2021/06/03 07:49

投稿

ozwk
ozwk

スコア13528

test CHANGED
@@ -1 +1,59 @@
1
1
  (x list)とカッコがついているのでxが関数と推論されているのでは?
2
+
3
+
4
+
5
+
6
+
7
+ ---
8
+
9
+
10
+
11
+ `assoc x list`にすると型が合わないと怒られる問題について:
12
+
13
+
14
+
15
+ ```ocaml
16
+
17
+ type exp =
18
+
19
+ | Num of int
20
+
21
+ | Var of string
22
+
23
+ | Add of exp * exp
24
+
25
+ | Mul of exp * exp;;
26
+
27
+
28
+
29
+ //...
30
+
31
+
32
+
33
+ let rec eval list var =
34
+
35
+ match var with
36
+
37
+ |Num n -> n
38
+
39
+ |Var x -> assoc x list
40
+
41
+ |Add (x, y) -> calc calc (eval (var));;
42
+
43
+
44
+
45
+ ```
46
+
47
+
48
+
49
+ とあるので evalの最初のパターンマッチの返り値`n`は`int`ですが、
50
+
51
+ その次の返り値 `assoc x list`の型は`'a option`と何かしらのオプション型なので
52
+
53
+ 型が全然合ってません。
54
+
55
+
56
+
57
+
58
+
59
+ とりあえず(全部消してイチから)全部の関数に型を明示して書いてはどうでしょう。