【发布时间】:2016-06-26 17:52:12
【问题描述】:
我正在尝试找到一种方法来翻译正常的递归符号,例如 作为 |fib|功能如下箭头,保留尽可能多的 递归符号的结构尽可能。另外我会 喜欢检查箭头。为此,我创建了一个包含 每个 Arrow{..} 类的构造函数:
谎言:
fib 0 = 0
fib 1 = 1
fib n = fib (n-2) + fib (n-1)
我的 R 数据类型,该数据类型的实例由映射组成 到适当的构造函数:
data R x y where
-- Category
Id :: R a a
Comp :: R b c -> R a b -> R a c
-- Arrow
Arr :: (a -> b) -> R a b
Split :: R b c -> R b' c' -> R (b,b') (c,c')
Cache :: (a -> a -> Bool) -> R a a
-- ArrowChoice
Choice :: R b c -> R b' c' -> R (Either b b') (Either c c')
-- ArrowLoop
Loop :: R (b, d) (c, d) -> R b c
-- ArrowApply
Apply :: R (R b c, b) c
翻译|fib|上面的函数首先导致 以下定义。然而,由于 proc n on,这是不允许的 |fibz| 的声明的 RHS。我知道 箭头符号阻止了这一点,但根本原因是什么 这个?
fib' :: (ArrowChoice r, ArrowLoop r) => r Int Int
fib' = proc x -> do
rec fibz <- proc n -> case n of
0 -> returnA -< 0
1 -> returnA -< 1
n' -> do l <- fibz -< (n'-2)
r <- fibz -< (n'-1)
returnA -< (l+r)
fibz -<< x
重写上面的函数以使用 let 语句编译。然而, 这里出现了我的第二个问题。我希望能够检查 递归发生的地方。然而,在这种情况下 |fibz|是一个 无限树。我想将递归捕获到 fibz,我 希望rec 能结合|loop|帮助我但 也许我错了?
fib'' :: (ArrowChoice r, ArrowLoop r, ArrowApply r) => r Int Int
fib'' = proc x -> do
let fibz = proc n -> case n of
0 -> returnA -< 0
1 -> returnA -< 1
n' -> do l <- fibz -< (n'-2)
r <- fibz -< (n'-1)
returnA -< (l+r)
fibz -<< x
基本上,可以观察到这种递归吗? (也许 即使在箭头符号的范围内)我也许可以添加 另一个构造函数,如修复。也许我应该能够观察变量的绑定,以便引用它们成为可能。不过,这将超出 Arrows 的范围。
对此有什么想法吗?
更新 1:
我想出了这种形式,在箭头符号之外。这隐藏了app 内的递归,因此我最终得到了箭头的有限表示。但是,我仍然希望能够例如将app 内的fib 调用替换为fib 的优化版本。
fib :: (ArrowChoice r, ArrowLoop r, ArrowApply r) => r Int Int
fib
= (arr
(\ n ->
case n of
0 -> Left ()
1 -> Right (Left ())
n' -> Right (Right n'))
>>>
(arr (\ () -> 0) |||
(arr (\ () -> 1) |||
(arr (\ n' -> (n', n')) >>>
(first ( arr (\ n' -> app (fib, n' - 2))) >>>
arr (\ (l, n') -> (n', l)))
>>>
(first (arr (\ n' -> app (fib, n' - 1))) >>>
arr (\ (r, l) -> (l + r)))))))
此代码对应于以下箭头符号:
fib :: (ArrowChoice r, ArrowLoop r, ArrowApply r) => r Int Int
fib = proc n ->
case n of
0 -> returnA -< 0
1 -> returnA -< 1
n' ->
do l <- fib -<< (n'-2)
r <- fib -<< (n'-1)
returnA -< (l+r)
【问题讨论】:
-
你会如何将
fib写成R? -
@SjoerdVisscher 我更新了问题以将
fib包含在R中。 (但使用类方法) -
reddit 正在同时进行讨论。