在Haskell中编写带有(广义)箭头的阶乘

在Haskell中编写带有(广义)箭头的阶乘,haskell,typeclass,arrows,Haskell,Typeclass,Arrows,我想在Haskell的(>)箭头中写一个阶乘。我不知道如何将递归转换为循环。我已经设法使用循环为我的阶乘建立了一个固定点,但是现在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]

我想在Haskell的
(>)
箭头中写一个阶乘。我不知道如何将递归转换为
循环
。我已经设法使用
循环
为我的阶乘建立了一个固定点,但是现在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]
,但我对这种情况不感兴趣。我要找的是更多


如何在
(>)
arrow中编写阶乘?

这里是Haskell-arrow符号中阶乘函数的等效递归定义

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)

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

一种可能性是首先将递归转换为使用
fix
,然后使用
循环
实现
fix

import Control.Arrow

fix :: (a -> a) -> a
fix = loop (\(f, x) -> let x' = f x in (x', x'))
或使用箭头符号指向自由点:

fix = loop (uncurry ($) >>> (id &&& id))

循环
只是
箭头
修复
版本
g
已经是要循环的箭头。所以我猜你已经设法在
(>)
箭头中编写了阶乘。
g
已经是一个箭头:它的类型是
(Int->Int,Int)->(Int->Int,Int)
@fizruk我正在尝试将整个函数分解为箭头原语。假设没有
arr
构造函数。这里有一个例子:@Owen@fizruk嗯,顺便说一句,我做到了。花了一些时间和两个问题在
cstheory
上找出其中一个上有一个GArrowLoop。当我知道这只是追踪单倍体范畴的另一个例子时,我写了它。
fix = loop (uncurry ($) >>> (id &&& id))