我想基于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派遣两种类型?
P.S。对不起,如果这个问题中的任何内容都是笨拙的措辞。我想在这里给自己一个挑战,我不完全理解我想要做的事情。
编辑:我的解决方案不受限制,我不必使用ContT
。
答案 0 :(得分:0)
您的命令都需要是返回相同类型的闭包(例如IO ()
,在这种情况下您不能执行getChar
)或者您需要具有可以执行的多态结果类型保持IO ()
或IO Char
,ContinueIO
需要将此作为参数。然后,您需要确定将IO Char
传递给GetChar
或将任何内容传递给PutChar
时会发生什么。 (此版本可以是Monoid
<> = ContinueIO
和mempty = id
,然后您可以foldMap
覆盖任何Foldable
结构。)