如何从ContT派遣不同类型?

时间:2018-01-05 01:13:43

标签: haskell monads monad-transformers continuations continuation-passing

我想基于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之类的东西一起运行。但是,PutCharGetChar命令在其类型中存在冲突。如何从同一个ContT派遣两种类型?

P.S。对不起,如果这个问题中的任何内容都是笨拙的措辞。我想在这里给自己一个挑战,我不完全理解我想要做的事情。

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

1 个答案:

答案 0 :(得分:0)

您的命令都需要是返回相同类型的闭包(例如IO (),在这种情况下您不能执行getChar)或者您需要具有可以执行的多态结果类型保持IO ()IO CharContinueIO需要将此作为参数。然后,您需要确定将IO Char传递给GetChar或将任何内容传递给PutChar时会发生什么。 (此版本可以是Monoid <> = ContinueIOmempty = id,然后您可以foldMap覆盖任何Foldable结构。)