我想在Haskell的(->)
箭头中写一个阶乘。我不知道如何将递归转换为loop
。我已经设法使用loop
为我的阶乘做了一个修复点,但现在有一个lambda-abstraction的问题,我无法翻译。
loop f b = let (d, c) = f (d, b) in c
g = \(f, x) -> (\x -> if x == 0 then 1 else x * f (x - 1), f x)
main = print $ loop g 5
在另一个箭头中编写阶乘的article转换了流:[a] -> [b]
,但我并不感兴趣。我正在寻找的更多like that
如何在(->)
箭头中编写因子?
答案 0 :(得分:1)
这是Haskell箭头符号中的阶乘函数的等效递归定义。
fact :: Integer -> Integer
fact = proc b -> do
rec
c <- f -<< b
f <- g -< f
returnA -< c
g :: (Integer -> Integer) -> Integer -> Integer
g f x = if x == 0 then 1 else x * f (x-1)
递归块的第二行表明了阶乘函数是g
的固定点这一事实。在第一行中,需要更高阶的箭头应用-<<
,因为f
也是块内的箭头。该行也可以写成
c <- app -< (f,b)
通过仅定义数据,即没有高阶箭头应用,是否可以在递归箭头符号中定义是不可能的。
答案 1 :(得分:1)
一种可能性是首先将递归转换为使用fix
,然后使用fix
实现loop
:
import Control.Arrow
fix :: (a -> a) -> a
fix = loop (\(f, x) -> let x' = f x in (x', x'))
使用箭头符号表示无点:
fix = loop (uncurry ($) >>> (id &&& id))