Экземпляр функции для ArrowLoop содержит
loop :: ((b,d) -> (c,d)) -> (b -> c)
loop f b = let (c,d) = f (b,d) in c
Сначала у меня проблема с сигнатурой: как мы можем получить b -> c из (b,d) -> (c,d)? Я имею в виду, что c в полученном кортеже может зависеть от обоих элементов ввода, как можно "отрезать" влияние d?
Во-вторых, я не понимаю, как работает let. Не содержит (c,d) = f (b,d) циклическое определение для d? Откуда приходит d? Честно говоря, я удивлен, что это допустимый синтаксис, поскольку, похоже, мы бы пересмотрели d.
Я имею в виду, что в математике это имело бы смысл, например. f может быть сложной функцией, но я бы предоставил только реальную часть b, и мне нужно было бы выбрать мнимую часть d таким образом, чтобы она не менялась, когда я оценивал f (b, d), что сделало бы ее некоторая фиксированная точка. Но если эта аналогия имеет место, выражение let должно каким-то образом "искать" для этой неподвижной точки для d (и может быть больше одного). Которая выглядит близко к магии для меня. Или я считаю слишком сложным?