2012-05-04 112 views
2

我知道作爲一個事實,我們不能獨立實現IO monad,但我不知道爲什麼。這段代碼試圖用函數式語言來實現一個命令式的範例。你能解釋一下這個例子和真正的IO之間的區別嗎?它看起來像函數main實現正確的操作順序,並保持懶惰。Haskell內部的IO實現

import System.IO.Unsafe 

data Io a = Io a 

runIO :: Io a -> a 
runIO (Io a) = a 

instance Monad Io where 
return x = Io x 
Io a >>= f = f a 

-- internal side effect function 
output :: Show a => a -> Io() 
output s = return $! unsafePerformIO $ print s 

---------------------------------------------------------------- 

mainIO :: Io()        
mainIO = do output "A" 
      b <- return "B" 
      output b  
      output b 
      x <- return (undefined :: String) 
      return undefined 
      output "C"  
      head [output "C", output "C"] 
      output x 
      output "D" 

test = runIO mainIO 

輸出:

"A" 
"B" 
"B" 
"C" 
"C" 
<interactive>: Prelude.undefined 

回答

11

我不知道你想顯示什麼。你已經在Haskell中嵌入了編碼IO,使用IO的現有實現作爲目標。

關鍵是你使用unsafePerformIOprint ---你從其他IO系統借用的原語。

考慮:如果您沒有任何其他IO系統依靠,該怎麼辦。所以沒有print或其他方式來調用基本IO功能。你將如何實現IO?

所以,儘管你可以在Haskell中以很多方式實現IO抽象,但你總是必須使用新的運行時原語函數來實際調用操作系統來執行真正的IO。這是Haskell本身無法實現的一點。


作爲參考,見博士論文"A Functional Specification of Effects",沃特Swierstra,這給的IO和其他效果已在Haskell被編碼的各種方式的概述,並且限定IO的說明書作爲一個純功能的數據類型(這是你所做的一些擴展)。

enter image description here

+0

感謝您的回覆和參考!我在這個網站上是新的,所以如果我稍後在這個主題中提出一些問題,有人會注意到它嗎?或者創建一個新的話題會更好嗎? – user1374768

+0

順便說一下,我的問題出現在閱讀本教程http://www.haskell.org/haskellwiki/IO_inside和本文http://webcache.googleusercontent.com/search?q=cache:ry-JwgJnib0J:research之後。 microsoft.com/pubs/67066/imperative.ps.z+hl=ru(a,RealWorld) – user1374768

+0

這裏使用了定義爲RealWorld - >(a,RealWorld)的IO類型,因此使用假參數來實現動作序列真實世界。但恕我直言,這種模式是不可能的純語言沒有外部編譯器黑客。所以我想知道爲什麼使用這個實現,希望pdf有更明確的解釋。 – user1374768