我有一个功能
// Will perform a given function twice
let twice f = (fun x -> f (f x))
然后我有类似的东西。
// Take x add 1
let f x = x+1
根据我两次调用的方式,它与左关联性的行为不同。
(twice (twice (twice (twice f)))) 0;; // Outputs 16
twice twice twice twice f 0;; // Outputs 65536
如果我再添加两次我的程序会执行StackOverflow,但到目前为止它似乎没有模式,这让我发疯。
设k是调用twice
的次数。
非咖喱是2 ^ k得到答案。
Curried非常奇怪。 假设1:当调用次数小于4时,它看起来像2 ^(2 ^(k-1)),但当k为4时,它的行为类似于2 ^(2 ^ k)< / p>
有没有人看到这种模式?或者你可以运行它超过k = 4来证明它吗?
答案 0 :(得分:3)
这是简单的优先规则,表现很奇怪(提示是65536 = 2 ^ 16)。在第二种情况下,您实际上是在创建指数的f调用而不是预期的线性增长。
当您在第二个案例中展开一个图层时,您将获得
twice twice twice (twice twice twice (f)) 0
,当您撰写更多twice
答案 1 :(得分:1)
事实上,这完全取决于相关性。当你写作时,
let x1 = twice twice twice twice f 0
等于
let x11 = (((twice twice) twice) twice) f 0
这导致了呼叫顺序的指数增长:每个twice
呼叫应该调用f x
两次。相反,它递归调用自身,而只有最内在的调用会调用f
。
您可以查看该函数的原型:
let y1: ( _ -> _ -> int) = twice twice twice twice
// val y1: ((int -> int) -> int -> int)
使关联性能很好的最小代码是:
// note we need to specify a type here
let y2: ( _ -> _ -> int) = twice >> twice >> twice >> twice
// the same with all arguments
let x2 = (twice >> twice >> twice >> twice) f 0
或
let y3 = f |> twice |> twice |> twice |> twice
let x3 = (f |> twice |> twice |> twice |> twice) 0