gpt4 book ai didi

haskell - 重新包装单子(monad)——任何通用的方式?

转载 作者:行者123 更新时间:2023-12-03 23:23:32 25 4
gpt4 key购买 nike

给定两个单子(monad),Monad mMonad n ,我想改造m (n a)进入 n (m a) .但是似乎没有通用的方法,因为 (>>=)return只处理一种单子(monad)类型,尽管 (>>=)允许从 monad 中提取内容,您必须将它们打包回相同的 monad 类型,以便它可以成为结果值。

但是,如果我们设置 m到了固定类型,工作就变得容易了。拍Maybe举个例子:

reorder :: (Monad n) => Maybe (n a) -> n (Maybe a)
reorder Nothing = return Nothing
reorder (Just x) = do
x' <- x
return $ Just x'

或列表:
reorder :: (Monad n) => [n a] -> n [a]
reorder [] = return []
reorder (x:xs) = do
x' <- x
xs' <- reorder xs
return (x':xs')

不难看出,我们这里有一个模式。为了更明显,把它写在 Applicative方式,它只不过是将数据构造函数应用于每个元素:
reorder (Just x) = Just <$> x
reorder (x:xs) = (:) <$> x <*> (reorder xs)

我的问题是:是否已经存在描述此类操作的 haskell 类型类,还是我必须自己发明轮子?

我在 GHC 文档中进行了简短的搜索,并没有发现任何对这个主题有用的东西。

最佳答案

Data.Traversable提供您正在寻找的内容:

sequenceA :: (Traversable t, Applicative f) => t (f a) -> f (t a)

GHC 甚至提供对自动派生实例的支持:
{-# LANGUAGE DeriveFunctor, DeriveFoldable, DeriveTraversable #-}
import Data.Foldable
import Data.Traversable

data List a = Nil | Cons a (List a)
deriving(Functor, Foldable, Traversable)

关于haskell - 重新包装单子(monad)——任何通用的方式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9684252/

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