3

事実として、IO モナドを独立して実装できないことは知っていますが、正確な理由はわかりません。このコードは、関数型言語を使用して命令型パラダイムを実装しようとする試みです。この例と実際の IO の違いを説明できますか? 関数 main は正しいアクション順序を実装しているように見えますが、怠惰なままです。

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
4

1 に答える 1

11

何を見せようとしているのかわからない。の既存の実装をターゲットとしてIO使用して、Haskell にのエンコーディングを埋め込みました。IO

重要なのは、他の IO システムから借用しているプリミティブの使用unsafePerformIO と--- です。print

考えてみてください: 他に依存する IO システムがなかったらどうなるでしょうか。したがって、printプリミティブ IO 関数を呼び出す方法はありません。IO をどのように実装しますか?

したがって、Haskell ではさまざまな方法で IO 抽象化を実装できますが、実際の IO を実行するためにオペレーティング システムを実際に呼び出すには、常に新しいランタイム プリミティブ関数を使用する必要があります。これは、Haskell でネイティブに実装できないビットです。


参考として、Haskell で IO やその他の効果がエンコードされたさまざまな方法の概要を説明している Wouter Swierstraの博士論文「A Functional Specification of Effects」を参照してください。あなたがしたことの延長の)。

ここに画像の説明を入力

于 2012-05-04T11:47:16.920 に答える