1

我想基于ContT. 我创建了一个 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。但是,PutCharandGetChar命令的类型有冲突。如何从同一个 ContT 分派两种类型?

PS对不起,如果这个问题中的任何内容措辞尴尬。我想在这里给自己一个挑战,但我并不完全明白我在做什么。

编辑:我的解决方案不受限制,我不必使用ContT.

4

1 回答 1

0

要么你的命令都需要是返回相同类型的闭包(例如IO (),在这种情况下你不能这样做getChar),要么你需要一个多态的结果类型,它可以包含IO ()or IO Char,并且ContinueIO需要把它作为它的参数。然后你需要决定当你传递一个IO ChartoGetChar或什么都不传递 to 时会发生什么PutChar。(这个版本可以是一个Monoidwith<> = ContinueIOmempty = id,然后你可以foldMap覆盖任何Foldable结构。)

于 2018-01-05T02:53:55.570 回答