2011-09-16 77 views
5

我是Haskell的新手。我写我自己的单子是国家单子错误处理:如何将IO添加到Haskell中的我自己的monad中?

newtype MyMonad a = MyMonad (State -> Either MyError (State, a)) 

我用它在一个小语种的翻译。现在我想将一些IO操作添加到我的语言中(读/写),但我不知道如何在我的内部封装IO monad。我知道我可以结合ErrorT,StateT,IO并实现这个结果,但有没有其他方法可以做到这一点?

回答

6

你可以看一下StateT是如何实现的:

newtype StateT s m a = StateT { runStateT :: s -> m (a,s) } 

要与IO结合状态,你只要把IO到位的m并获得所需的类型:s -> IO (a,s)

如果您也有错误,这将变得类似于s -> IO (Either e (a, s))s -> IO (Either e a, s),具体取决于您希望失败的计算是否影响状态。

请注意,如果没有时间机器,您不能使s -> Either e (IO (a, s))单元

更新

事实证明,你不能让它即使有时间机器单子。

说明为什么它是不可能的,让我们通过使用()代替s第一简化我们的单子:data M e a = M { runM :: Either e (IO a) }

现在,想象一下下面的程序:

unsafePerformIO :: IO a -> a 
unsafePerformIO io = fromLeft $ runM $ do 
    a <- M $ Right $ io 
    M $ Left a 

显然,这个功能是不可能的,因此M的monad实例也是不可能的。

机器可以给你什么时间能够治疗IO就像一个对待State。但是,我并没有意识到,Either e (s -> (a, s))不是一个monad。

+0

时光机?你能提供一些背景吗?这是一些“双关语”的笑话,还是一些高级的数学/编程科学术语? – Tarrasch

+1

这里没有双关语,我正在谈论一个真正的时间机器。一旦你有了它,你可以实现这个monad。 – Rotsor

+1

@Rotsor:谨慎地解释*为什么*说时间机器是必需的? – ivanm

相关问题