gpt4 book ai didi

haskell - 是否有一种通用方法可以将失败 monad 上的免费 comonad 分解为 “values stream and final error” ?

转载 作者:行者123 更新时间:2023-12-02 14:21:45 25 4
gpt4 key购买 nike

Cofree comonad 对于以错误类型多态的方式迭代部分函数很有用。它的coiter类似于错误单子(monad)中的 forM 循环,但它以纯粹/惰性的方式收集生成的值,并且您只能在数据结构的末尾看到错误。

例如,Cofree Identity(不允许失败!)是无限流,而 Cofree MaybeNonEmpty 同构,并且 Cofree (Either e) a 基本上是 (NonEmpty a, e) (成功迭代值的列表加上最后发生的错误)。

现在我想知道评估结果的最佳方法是什么,而不需要对单个错误单子(monad)进行特定的模式匹配。由于 Foldable 实例(例如 toList),提取所有非常容易,但我不确定如何最好地掌握错误。可以利用 Foldable 来删除值并保留错误部分:

vals'n'err :: (Monad m, Foldable m)
=> Cofree m a -> (NonEmpty a, (m ()))
vals'n'err (a :< q) = case toList q of
[] -> (a:|[], const () <$> q)
l -> first (pure a<>)
$ foldr1 (\(bs,e) (cs,f) -> (bs<>cs, e>>f)) $ vals'n'err<$>l

但这感觉有点hackish。有更好的解决办法吗?

最佳答案

我认为这对于大流来说是不好的转换,因为你可能会因为懒惰而导致空间泄漏。但对于小流来说它可能有用。

我们可以将这个转换分为两部分:

vals :: Foldable f => Cofree f a -> NonEmpty a
vals = NonEmpty.fromList . Foldable.toList

err :: Monad m => Cofree m a -> m b
err (_ :< m) = m >>= err

然后组合在一起:

vals'n'err :: (Monad m, Foldable m) => Cofree m a -> (NonEmpty a, m b)
vals'n'err w = (vals w, err w)

关于haskell - 是否有一种通用方法可以将失败 monad 上的免费 comonad 分解为 “values stream and final error” ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41282795/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com