【发布时间】:2018-06-14 19:25:09
【问题描述】:
我想创建一个基于ContT 的通用形式的IO。我创建了一个 GADT 来表示不同的 IO 操作:
data Cmd a where
PutChar :: Char -> Cmd ()
GetChar :: Cmd Char
我编写了一个函数,将这些转换为IO 命令,以便在 IO monad 中使用,如下所示:
continueIO :: Cmd a -> IO a
continueIO (PutChar c) = putChar c
continueIO GetChar = getChar
下面是它的示例用法:
echoChar :: (Monad m) => ContT r m (Cmd a)
echoChar = ContT $ \k -> do
c <- k GetChar
k (PutChar c)
它应该使用runContT echoChar continueIO 之类的东西运行。但是,PutChar 和 GetChar 命令的类型存在冲突。如何从同一个 ContT 分派这两种类型?
附:抱歉,如果这个问题中的任何内容措辞尴尬。我想在这里给自己一个挑战,但我不完全明白我在做什么。
编辑:我的解决方案不受限制,也不必使用ContT。
【问题讨论】:
-
您是否仅限在此处使用
ContT?这正是Free或Operational旨在处理的那种情况。 -
@Carl 我完全不受限制,我绝对愿意探索这些解决方案。谢谢!
-
@Carl,我认为
FT Cmd m比Free Cmd更有可能。 -
您可能需要一个存在包装器。不过,很难理解您是否真的需要它。
标签: haskell monads monad-transformers continuations continuation-passing