ArrowLoop
的函数实例包含:
loop :: ((b,d) -> (c,d)) -> (b -> c)
loop f b = let (c,d) = f (b,d) in c
首先,我有一个关于签名的问题:我们怎么可能从 (b,d) -> (c,d)
得到 b -> c
?我的意思是,结果元组中的 c
可能取决于输入的两个元素,如何“切断” d
的影响?
其次,我不明白这里的 let
是如何工作的。 (c, d) = f(b, d)
不包含对 d
的循环定义吗? d
从哪里来?说实话,我很惊讶这是有效的语法,因为它看起来像是重新定义了 d
。
我的意思是,在数学上,这有一定的道理,例如 f 可以是一个复合函数,但我只提供实部 b,我需要选择虚部 d 的方式,使得当我计算 f(b,d) 时它不变,这将使它成为某种固定点。但是,如果这个类比成立,那么 let
表达式必须以某种方式“搜索”该固定点的 d(可能会有多个)。这对我来说看起来很神奇。还是我想得太复杂了?