这个“计数”是否是一个突变?

问题描述 投票:0回答:2
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必须接收一个类型unit - > int函数作为第一个参数。我调用函数后检查了计数并得到0,所以可以这样写,对吧?但是,它确实感到邋..

添加了上下文(函数g和使用的数据类型)。函数count_wcs应该计算通配符模式在模式中出现的数量。

sml
2个回答
0
投票

这不算作突变,但它确实类似于你拥有它们时可能会做的事情,并且可能不会起作用,这取决于你正在做什么。突变需要参考,它们是用ref制作的,并且用!取消引用。所以只要远离那些。 :-)

你正在做一些没有什么好处的事情:

let
  val count = 0
in
  ...
end

count绑定为0,但绝不会导致count具有任何其他值;我认为你想最终让count增加。如果它是一个引用,val count = ref 0,你可以通过做count := !count + 1来增加它,但是因为它不是,你必须使count成为某个函数的变量才能改变它。

例如:

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的函数执行其他操作,例如从程序外部的源读取或写入。

我不会称之为草率。只是有点奇怪,不知道上下文。


0
投票

在标准ML中识别突变非常容易 - 如果你不使用ref变量并用:=赋予它们新的值,那么它就不是突变。 你不这样做,所以你不会改变任何事情。

此外,您的功能可以简化为

fun count_wildcards p = g (fn () => 1) (fn _ => 1) p

这使得更清楚的是没有任何变异。 (它根本不清楚它应该完成什么,因此无法确定您的解决方案是否正确。)

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.