我实现了monad变换器MaybeT
。
newtype MaybeT m a =
MaybeT { runMaybeT :: m (Maybe a) }
然后,我写了一个monad用于回溯。
newtype BackT m a =
BackT { unBackT :: MaybeT m (a, BackT m a) }
这里,Back m a
具有递归定义。
在我看来,有同构。
unBackT
BackT m a <-------------------> MaybeT m (a, BackT m a)
BackT(constructor)
runMaybeT
MaybeT m (a, BackT m a) <------------------> m (Maybe (a, BackT m a))
MaybeT(constructor)
因此,我实际上得到了像
这样的东西m (Just(1, m (Just(2, m (Just(3, m (Just(4, Nothing))))))))
在上面给出的例子中,有4个计算(Monad是计算?)。我需要一些名为runBackT
的内容来使用[]
来收集它们。
感谢@rampion的回答,我删除了一些毫无意义的问题。
m
。m a
。)m a
并不能保证有办法获得&#34;解包&#34;类型。)[a]
。这样的BackT m a -> [a]
函数是否存在?或者,我们只能获得m [a]
吗? (答案:只有BackT m a -> m [a]
可能存在。)更新
Monad可以分为两类:&#34;打开monad&#34; (例如[]
,Maybe
)和&#34;封闭的monad&#34; (如IO
)。 &#34;打开monad&#34;具有类型m a -> b
的函数来打开它们。 e.g。
showMaybe :: (Show a) => Maybe a -> String
showMaybe mx = case mx of
Nothing -> "Nothing"
Just x -> show x
(Monad m, Show m) => BackT m a -> [String]
?Monad m => (m a -> b) -> BackT m a -> [b]
?Monad m => BackT m a -> [m a]
是否存在? BackT m a
序列计算m a
通过交叉递归定义递归。如何将其更改为迭代[m a]
?如果存在,如何实现呢?我们可以将m a -> b
映射到[m a]
,问题(2)将会得到解决。Monad m => (m a -> a) -> BackT m a -> m [a]
?只需用构造函数m
包装问题(2)的结果。因此,关键点是问题(3)。
对我来说最困难的部分是BackT m a
的递归定义。如果您能展示工具或分享一些建议,我会很感激。
仅针对问题(3)的答案是可以的。
更新
感谢@rampion的评论,ListT
from list-t package回答了我的问题。
答案 0 :(得分:2)
如何在示例中收集
1, 2, 3, 4
之类的所有参数。它的类型应该是[a]
。这样的BackT m a -> [a]
函数是否存在?或者我们只能获得m [a]
?
首先想到这一点。
我们当然可以获得BackT m a
的{{1}}值:
Monad m
凭借Prelude> emptyBackT = BackT (MaybeT (return Nothing))
Prelude> :t emptyBackT
emptyBackT :: Monad m => BackT m a
的强大功能,我们可以将fmap
转换为m a
任何BackT m a
的{{1}}:
Functor m
因此,如果我们有办法转换任何Prelude> lift ma = BackT (MaybeT (fmap (\a -> Just (a, emptyBackT)) ma))
Prelude> :t lift
lift :: Monad m => m a -> BackT m a
,我们可以将其与BackT m a -> [a]
结合使用,以获得lift
的{{1}}!
但我们知道我们不能在Haskell中做到这一点。一些仿函数(如m a -> [a]
或Functor m
)展开,但还有其他仿函数(如[]
)不能。
因此Maybe
需要输入IO
类型。
至于实施,这里有一些主要问题。
你有runBackT
到BackT m a -> m [a]
的同构,所以
BackT m a
已经实施,您可以实施m (Maybe (a, BackT m a))
吗?runBackT :: BackT m a -> m [a]
已经实施,您可以实施consBackT :: a -> BackT m a -> m [a]
吗?runBackT :: BackT m a -> m [a]
已经实施,您可以实施unwrapBackT :: Maybe (a, BackT m a) -> m [a]
吗?(提示:我在主要问题中使用的类型不完整)