【发布时间】:2015-05-23 14:10:15
【问题描述】:
我有一个由FreeT生成的标准解释器monad转换器的简化版本:
data InteractiveF p r a = Interact p (r -> a)
type Interactive p r = FreeT (InteractiveF p r)
p 是“提示”,r 是“环境”...可以使用类似的方式运行它:
runInteractive :: Monad m => (p -> m r) -> Interactive p r m a -> m a
runInteractive prompt iact = do
ran <- runFreeT iact
case ran of
Pure x -> return x
Free (Interact p f) -> do
response <- prompt p
runInteractive prompt (f resp)
instance MonadFix m => MonadFix (FreeT (InteractiveF p r)) m a)
mfix = -- ???
我觉得这种类型或多或少只是StateT 的受限版本...如果有的话,Interactive p r IO 是IO 的受限版本...我认为...但是。 ..好吧,无论如何,我的直觉说应该有一个很好的例子。
我试过写一个,但我似乎无法弄清楚。到目前为止,我最接近的尝试是:
mfix f = FreeT (mfix (runFreeT . f . breakdown))
where
breakdown :: FreeF (InteractiveF p r) a (FreeT (InteractiveF p r) m a) -> a
breakdown (Pure x) = x
breakdown (Free (Interact p r)) = -- ...?
我还尝试使用利用m 的MonadFix 实例的版本,但也没有运气--
mfix f = FreeT $ do
rec ran <- runFreeT (f z)
z <- case ran of
Pure x -> return x
Free iact -> -- ...
return -- ...
任何人都知道这是否真的有可能,或者为什么不可能?如果是,有什么好地方让我继续寻找?
另外,在我的实际应用中,我什至不需要使用FreeT...我可以使用Free;也就是说,让Interactive 只是一个 monad 而不仅仅是一个 monad 转换器,并且有
runInteractive :: Monad m => (p -> m r) -> Interactive p r a -> m a
runInteractive _ (Pure x) = return x
runInteractive prompt (Free (Interact p f) = do
response <- prompt p
runInteractive prompt (f response)
如果这个案例有可能,而不是一般的 FreeT 案例,我也会很高兴 :)
【问题讨论】:
-
@shang 问题完全不同..另一个问题是问是否可以编写多态通用 mfix,而我问的是具体类型:)
标签: haskell monads free-monad monadfix