2011-09-16 80 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

相關問題