[Haskell-cafe] Haskell soltion ofr I/O: is it monads or
uniqueness types, after all?
Lennart Augustsson
lennart at augustsson.net
Sat Feb 10 16:22:57 EST 2007
Hbc implements the IO type by request/response IO. I.e., the original
Haskell I/O system. People who assume IO involves some RealWorld being
passed around are just making unwarranted assumptions. The Haskell
definition leaves the IO type abstract.
-- Lennart
On Feb 10, 2007, at 19:16 , Stefan O'Rear wrote:
> Gah. For the first time ever, I seem to have accidentally done a
> reply to
> sender. (IE Bulat please ignore this message)
>
> On Sat, Feb 10, 2007 at 07:25:19PM +0300, Bulat Ziganshin wrote:
>> Hello haskell-cafe,
>>
>> just another interesting discussion in russian forum raised such
>> idea:
>>
>> we all say that monads are the haskell way to do i/o. is it true? may
>> be, uniqueness types, just like in Clean and Mercury, are real
>> way, and
>> monads are only the way to write programs that use uniqueness types
>> easier?
>>
>> so, IO monad is like any other monad - it simplifies writing of
>> complex code, but by itself it don't solve any problems. all code
>> that
>> can be written with monads can also be written using ordinal function
>> calls. we know it for IO monad too - in ghc, we can use low-level
>> representation of IO type and write imperative code without use of
>> any monad operators
>
> Just because Jhc, GHC, and Yhc (any others? any non-others?) all use
> RealWorld# tokens, doesn't mean it's the only way to implement IO.
> Note that unsafePerformIO will need to be a primitive...
>
> data Process = Getc (Char -Process)
> | Putc Char (() -Process)
> | forall a. NewIORef a (IORef a -Process)
> | forall a. ReadIORef (IORef a) (a -Process)
> | forall a. WriteIORef (IORef a) a (() -Process)
> | Exit
> {- IORef is specifically mentioned because it is the canonical
> example of something IO can do that 1.2-style streams can't -}
>
> type IO = Cont Process
> -- using Cont monad's monad
>
> getChar = Cont $ Getc
> putChar = Cont . Putc
> newIORef = Cont . NewIORef
> readIORef = Cont . ReadIORef
> writeIORef a b = Cont $ WriteIORef a b
> exit = Cont $ \_ -Exit
>
> {- in runtime, forgive my rusty C -}
>
> int main() {
> init_runtime_foo();
> thunk* tree = hseval("runCont main Exit")
>
> while(1) {
> whnf(tree);
> switch (tree->tag) {
> case _Getc:
> char ch = getchar();
> thunk* hch = hs_wrapchar(ch);
> tree = hsmkapp( tree->payload(0) , hch );
> continue;
> ...
> case _Exit:
> return 0;
> }
> }
> }
>
> of course, this doesn't refute the non-primitive-ness of IO, but it
> does refute
> the uniqueness types part.
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
More information about the Haskell-Cafe
mailing list