user1374768
user1374768

Reputation: 408

IO implementation inside Haskell

I know as a fact, that we cant implement an IO monad independently, but I dont know why exactly. This code is an attempt to implement an imperative paradigm using functional language. Can you explain the difference between this example and true IO? It looks like function main implements the correct action order and remains lazy.

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 

output:

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

Upvotes: 3

Views: 702

Answers (1)

Don Stewart
Don Stewart

Reputation: 137937

I'm not sure what you're trying to show. You've embedded an encoding of IO in Haskell, using the existing implementation of IO as a target.

The key is your use of unsafePerformIO and print --- primitives you're borrowing from the other IO system.

Consider: what if you didn't have any other IO system to lean on. So no print or other way to call primitive IO functions. How would you implement IO?

So while you can implement the IO abstraction many ways in Haskell, you always have to fall on new runtime primitive functions to actually call into the operating system to do real IO. That's the bit that can't be implemented in Haskell natively.


As a reference , see the PhD thesis "A Functional Specification of Effects", Wouter Swierstra, which gives an overview of various ways IO and other effects have been encoded in Haskell, and defines a specification of IO as a purely functional data type (kind of an extension of what you've done).

enter image description here

Upvotes: 11

Related Questions