The function instance for ArrowLoop
contains
loop :: ((b,d) -> (c,d)) -> (b -> c)
loop f b = let (c,d) = f (b,d) in c
First I have a problem with the signature: How can we possibly get b -> c
from (b,d) -> (c,d)
? I mean, the c
in the resulting tuple may depend on both elements of the input, how is it possible to "cut off" the influence of d
?
Second I don't get how the let
works here. Doesn't contain (c,d) = f (b,d)
a cyclic definition for d
? Where does d
come from? To be honest, I'm surprised this is valid syntax, as it looks like we would kind of redefine d
.
I mean in mathematics this would make kind of sense, e.g. f could be a complex function, but I would provide only the real part b, and I would need to chose the imaginary part d in a way that it doesn't change when I evaluate f (b,d), which would make it some kind of fixed point. But if this analogy holds, the let
expression must somehow "search" for that fixed point for d (and there could be more than one). Which looks close to magic to me. Or do I think too complicated?