3

我想(->)在 Haskell 中写一个阶乘箭头。我不明白如何将递归转换为loop. 我已经设法loop为我的阶乘创建了一个固定点,但现在 lambda 抽象存在问题,我无法翻译。

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

一篇关于在转换流的另一个箭头中编写阶乘的文章:[a] -> [b],但我感兴趣的不是这种情况。我正在寻找的更像是那个

如何在(->)箭头中写阶乘?

4

2 回答 2

1

一种可能性是首先将递归转换为 using fix,然后实现fixusing loop

import Control.Arrow

fix :: (a -> a) -> a
fix = loop (\(f, x) -> let x' = f x in (x', x'))

或使用箭头符号无点:

fix = loop (uncurry ($) >>> (id &&& id))
于 2014-07-17T20:29:38.317 回答
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)

目前尚不清楚是否可以通过仅定义数据以递归箭头表示法定义,即没有高阶箭头应用程序。

于 2014-07-16T22:03:30.870 回答