Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell Fix上的类mapAccumR递归方案?_Haskell_Recursion Schemes - Fatal编程技术网

Haskell Fix上的类mapAccumR递归方案?

Haskell Fix上的类mapAccumR递归方案?,haskell,recursion-schemes,Haskell,Recursion Schemes,我正在使用来自的函数,并努力弄清楚它是否提供了一些通用的mapAccumR。足以实现的功能,例如: f :: [Int] -> (Int,[Int]) f [] = (0,[]) f (x:xs) = let (sz,xs') = f xs in (sz+x, x*sz : xs') …在修复-ed结构的单次传递中,如: data L a as = Empty | C a as input :: Fix (L Int) input = Fix (C 1 (Fix (C 2 (Fix

我正在使用来自的函数,并努力弄清楚它是否提供了一些通用的
mapAccumR
。足以实现的功能,例如:

f :: [Int] -> (Int,[Int])
f [] = (0,[]) 
f (x:xs) = let (sz,xs') = f xs in (sz+x, x*sz : xs')
…在
修复
-ed结构的单次传递中,如:

data L a as = Empty | C a as

input :: Fix (L Int)
input = Fix (C 1 (Fix (C 2 (Fix Empty))))
似乎是我想要的,除了我需要访问最终的
b
(上面示例中的最终总和)


我的实际用例是在注释时对AST进行类型检查,并返回表达式的类型。

您希望通过
Fix f
调整值向上下降,同时像mapAccumR那样跟踪状态吗?这是向上顺序的
cataM
,状态的
monad用于跟踪状态。在您的示例中:

f :: Fix (L Int) -> (Fix (L Int), Int)
f = (`runState` 0) $ cataM $ ((.) . fmap) Fix $ \case
  Empty -> pure Empty
  C x xs -> do
    sz <- get
    put $ sz+x
    return $ C (x*sz) xs
都没有经过测试


或者您希望每个分支的状态都是本地的吗?

您希望使用哪种类型的签名?另外,您可能应该看看
para
。但是回到我的第一个问题,
mapAccumR
可遍历的
函子的一个已知概念;对于任意类型的不动点,它应该意味着什么还不太清楚。所以我认为
para
足够强大,可以实现
f
,但是在二次时间内,这是我不想要的。我想我也可以做两个
cata
,一个是标记和累积大小,另一个是再次从子树中删除这些大小,但我也不想这样做。你是对的,如果我认真考虑签名的话,我可能是回答我自己问题的最佳方式,但我想我已经决定无论如何这都是相当愚蠢的。
递归方案
的文档真的很棒。很明显,
zygo
是一条路要走。谢谢,我的实际示例是一个AST,我在其中一次检查并注释树。因此,在每个级别上,我们都需要访问子类型并为父类型返回一个类型。不过这里有几点,我很感激你的回答
makeClassyPrisms ''L

f = (`runState` 0) . transformMOf . _Fix . _C . _1 $ \x -> do
  sz <- id <<+= x
  return $ x*sz