gpt4 book ai didi

haskell - 一棵单子(monad)玫瑰树可以有一个 MonadFix 实例吗?

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

给定

newtype Tree m a = Tree { runTree :: m (Node m a) }
data Node m a = Node
{ nodeValue :: a
, nodeChildren :: [Tree m a]
}

有没有有效的 MonadFix实例?

我的尝试是
instance MonadFix m => MonadFix (Tree m) where
mfix f = Tree $ do
Node
<$> mfix (runTree . f . nodeValue)
<*> fmap nodeChildren (runTree (mfix f))

然而,当我实际尝试使用它时,这似乎并没有终止。该实例在某种程度上受到 MonadFix 的启发。列表的例子。

最佳答案

真正的解决方案真的来自gallais稍作修改。我们将核心理念提升到 containers图书馆,MonadFix Tree实例 here

{-# LANGUAGE DeriveFunctor #-}

module MonadTree where

import Control.Monad
import Control.Monad.Fix

newtype Tree m a = Tree { runTree :: m (Node m a) }
deriving (Functor)

data Node m a = Node
{ nodeValue :: a
, nodeChildren :: [Tree m a]
} deriving (Functor)

valueM :: Functor m => Tree m a -> m a
valueM = fmap nodeValue . runTree

childrenM :: Functor m => Tree m a -> m [Tree m a]
childrenM = fmap nodeChildren . runTree

joinTree :: Monad m => m (Tree m a) -> Tree m a
joinTree = Tree . join . fmap runTree

instance Monad m => Applicative (Tree m) where
pure a = Tree $ pure $ Node a []
(<*>) = ap
instance Monad m => Monad (Tree m) where
return = pure
m >>= k =
Tree $ do
Node x xs <- runTree m
Node y ys <- runTree (k x)
pure . Node y $
fmap (>>= k) xs ++ ys

instance MonadFix m => MonadFix (Tree m) where
mfix f = Tree $ do
node <- mfix $ \a -> do
runTree (f (nodeValue a))
let value = nodeValue node
let trees = nodeChildren node
let children = zipWith (\ k _ -> mfix (joinTree . fmap (!! k) . childrenM . f)) [0..] trees
return $ Node value children

关于haskell - 一棵单子(monad)玫瑰树可以有一个 MonadFix 实例吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47833188/

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