English 中文(简体)
What are the alternative of monads to use IO in pure functional programming?
原标题:

monads are described as the haskell solution to deal with IO. I was wondering if there were other ways to deal with IO in pure functional language.

最佳回答

What alternatives are there to monads for I/O in a pure functional language?

I m aware of two alternatives in the literature:

  • One is a so-called linear type system. The idea is that a value of linear type must be used exactly one time: you can t ignore it, and you can t use it twice. With this idea in mind, you give the state of the world an abstract type (e.g., World), and you make it linear. If I mark linear types with a star, then here are the types of some I/O operations:

    getChar :: World* -> (Char, World*)
    putChar :: Char -> World* -> World*
    

    and so on. The compiler arranges to make sure you never copy the world, and then it can arrange to compile code that updates the world in place, which is safe because there is only one copy.

    The uniqueness typing in the language Clean is based on linearity.

    This system has a couple of advantages; in particular, it doesn t enforce the total ordering on events that monads do. It also tends to avoid the "IO sin bin" you see in Haskell where all effectful computations are tossed into the IO monad and they all get totally ordered whether you want total order or not.

  • The other system I m aware of predates monads and Clean and is based on the idea that an interactive program is a function from a (possibly infinite) sequence of requests to a (possibly infinite) sequence of responses. This system, which was called "dialogs", was pure hell to program. Nobody misses it, and it had nothing in particular to recommend it. Its faults are enumerated nicely in the paper that introduced monadic I/O (Imperative Functional Programming) by Wadler and Peyton Jones. This paper also mentions an I/O system based on continuations which was introduced by the Yale Haskell group but which was short-lived.

问题回答

Besides linear types, there s also effect system.

If by "pure" you mean "referentially transparent", that is, that an applied function is freely interchangeable with its evaluated result (and therefore that calling a function with the same arguments has the same result every time), any concept of stateful IO is pretty much excluded by definition.

There are two rough strategies that I m aware of:

  • Let a function do IO, but make sure that it can never be called twice with the exact same arguments; this side-steps the issue by letting the functions be trivially "referentially transparent".

  • Treat the entire program as a single pure function taking "all input received" as an argument and returning "all output produced", with both represented by some form of lazy stream to allow interactivity.

There are a variety of ways to implement both approaches, as well as some degree of overlap--e.g., in the second case, functions operating on the I/O streams are unlikely to be called twice with the same part of the stream. Which way of looking at it makes more sense depends on what kind of support the language gives you.

In Haskell, IO is a type of monad that automatically threads sequential state through the code (similar to the functionally pure State monad), such that, conceptually, each call to an otherwise impure function gets a different value of the implicit "state of the outside world".

The other popular approach I m aware of uses something like linear types to a similar end; insuring that impure functions never get the same arguments twice by having values that can t be copied or duplicated, so that old values of the "state of the outside world" can t be kept around and reused.

Uniqueness typing is used in Clean

Imperative Functional Programming by Peyton Jones and Wadler is a must read if you are interested in functional IO. The other approaches that they discuss are:

  • Dialogues which are lazy streams of responses and requests

type Dialogue = [Response] -> [Request]

main :: Dialogue

  • Continuations - each IO operation takes a continuation as argument

  • Linear types - the type system restricts you in a way that you cannot copy or destroy the outside state, which means that you can t call a function twice with the same state.

Functional Reactive Programming is another way to handle this.

I was wondering if there were other ways to deal with IO in a pure functional language.

Just adding to the other answers already here:

  • The title of this paper says it all :-)
  • You could also look at:

Rebelsky S.A. (1992) I/O trees and interactive lazy functional programming. In: Bruynooghe M., Wirsing M. (eds) Programming Language Implementation and Logic Programming. PLILP 1992. Lecture Notes in Computer Science, vol 631. Springer, Berlin, Heidelberg

  • When Haskell was young, Lennart Augustsson wrote of using system tokens as the mechanism for I/O:

L. Augustsson. Functional I/O Using System Tokens. PMG Memo 72, Dept Computer Science, Chalmers University of Technology, S-412 96 Göteborg, 1989.

I ve yet to find a online copy but I have no pressing need for it, otherwise I suggest contacting the library at Chalmers.





相关问题
Interrupt driven HD44780 library for an Arduino

I have an HD44780 LCD screen, and I ve been using the LiquidCrystal Library provided with the Arduino development package. However, it s not reliable. I noticed some problems with it, and instead of ...

Appending lists from files to a single list in Python

I m trying to write a function that reads files from a "deferred" directory which contains files that contain lists. Here s what the files in the deferred folder contain: 173378981 , 45000 , ...

C# TCP/IP Client having an IO Exception

The IO Exception: "Unable to read data from the transport connection: An established connection was aborted by the software in your host machine." The code has been copied from a tutorial and I m ...

Java: Why isn t my file writing working?

I m trying to write a file from my Java program, but nothing happens. I m not getting any exceptions or errors, it s just silently failing. try { File outputFile = new File(args[...

Multithreading on a file open copy and write

I am new at threads here is the question, I have 3 threads one of them calls a method that writes into a file via File.AppendAllText method, other thread duplicates the text in the same file, and the ...

Is File.Exists an expensive operation?

Re: http://msdn.microsoft.com/en-us/library/system.io.file.exists.aspx Does anyone know if this is a particularly slow or locking operation which could impact server performance in a large ...

Removing pause after reading using readLine in java

I am reading several lines from the console in a java program using the readLine command from the BufferedReader class. However, the program pauses at the end of the last line and does not proceed ...

热门标签