如何从ContT派遣不同类型?

问题描述 投票:1回答:1

我想基于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发送这两种类型?

附:对不起,如果这个问题中的任何内容都是笨拙的措辞。我想在这里给自己一个挑战,我并不完全明白我在做什么。

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

haskell monads monad-transformers continuations continuation-passing
1个回答
0
投票

您的命令都需要是返回相同类型的闭包(例如IO (),在这种情况下您不能执行getChar)或者您需要具有可以容纳IO ()IO Char的多态结果类型,并且ContinueIO需要采取这是它的论点。然后你需要决定当你将IO Char传递给GetChar或者没有传递给PutChar时会发生什么。 (这个版本可能是Monoid<> = ContinueIOmempty = id,然后你可以foldMap任何Foldable结构。)

© www.soinside.com 2019 - 2024. All rights reserved.