fun count_wcs p =
let
val count = 0
in
g (fn () => count + 1) (fn y => 1) p
end
我正在做作业,我们不应该使用突变,这不会将值重新分配给任何值,但是感觉不正确。请不要说什么是正确的方法,因为我应该弄清楚这一点。
datatype pattern = Wildcard
| Variable of string
| UnitP
| ConstP of int
| TupleP of pattern list
| ConstructorP of string * pattern
fun g f1 f2 p =
let
val r = g f1 f2
in
case p of
Wildcard => f1 ()
| Variable x => f2 x
| TupleP ps => List.foldl (fn (p,i) => (r p) + i) 0 ps
| ConstructorP(_,p) => r p
| _ => 0
end
此函数g必须接收类型单元-> int函数作为第一个参数。我在调用该函数并得到0之后检查了计数,所以可以这样编写它,对吗?但是,它确实有点草率。
添加了上下文(函数g和使用的数据类型)。该功能count_wcs应该计算一个模式中出现的通配符模式的数量。
答案 0 :(得分:0)
这不算是突变,但确实与您拥有它们时可能执行的操作类似,并且可能无法正常工作,具体取决于您正在执行的操作。突变需要引用,它们是用ref
进行的,并用!
取消了引用。因此,请远离这些。 :-)
您正在做的事情将无济于事:
let val count = 0 in ... end
将count
绑定为0,但不会导致count
具有任何其他值;我假设您最终希望增加count
。如果它是一个引用val count = ref 0
,则可以通过执行count := !count + 1
来对其进行递增,但是由于不是,因此必须更改count
某个函数的变量才能对其进行更改。 / p>
例如:
fun count_4s ([], count) = count
| count_4s (x::xs, count) = count_4s (xs, if x = 4 then count + 1 else count)
在每个调用count
中,常量是常量,但在随后的每个递归调用中,它可能会递增。
此函数g必须接收类型 unit-> int 函数作为第一个参数。
... g (fn () => count + 1) (fn y => 1) p ...
[...] 但仍然感觉马虎。
假设g
的第一个参数没有副作用,并且不会引发异常并且不会永远循环,那么他们所能做的就是在每次调用时返回相同的内容。这使他们相当无聊。通常,以() : unit
作为输入或返回的函数会执行其他操作,例如从程序外部的源进行读取或写入。
我不会称其为马虎。有点奇怪,不知道上下文。
答案 1 :(得分:0)
在标准ML中识别突变非常容易-如果您不使用ref
变量,而用:=
为其赋予新值,则不是突变。
而且您不需要,所以您没有任何变异。
此外,您的功能可以简化为
fun count_wildcards p = g (fn () => 1) (fn _ => 1) p
这使得没有任何变异变得更加清晰。
(完全不清楚应该完成什么,因此无法确定您的解决方案是否正确。)