14.11.2012 Views

Curry: An Integrated Functional Logic Language

Curry: An Integrated Functional Logic Language

Curry: An Integrated Functional Logic Language

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

take a character (string) and produces an action which, when applied to a world, puts this character<br />

(string) to the standard output (and a line-feed in case of putStrLn.<br />

Since an interactive program consists of a sequence of I/O operations, where the order in the<br />

sequence is important, there are two operations to compose actions in a particular order. The<br />

function<br />

(>>) :: IO a -> IO b -> IO b<br />

takes two actions as input and yields an action as output. The output action consists of performing<br />

the first action followed by the second action, where the produced value of the first action is ignored.<br />

If the value of the first action should be taken into account before performing the second action,<br />

the actions can be composed by the function<br />

(>>=) :: IO a -> (a -> IO b) -> IO b<br />

where the second argument is a function taking the value produced by the first action as input and<br />

performs another action. For instance, the action<br />

getLine >>= putStrLn<br />

is of type IO () and copies, when executed, a line from standard input to standard output.<br />

The return function<br />

return :: a -> IO a<br />

is sometimes useful to terminate a sequence of actions and return a result of an I/O operation.<br />

Thus, return v is an action which does not change the world and returns the value v.<br />

To execute an action, it must be the main expression in a program, i.e., interactive programs<br />

have type IO (). Since the world cannot be copied (note that the world contains at least the<br />

complete file system), non-determinism in relation with I/O operations must be avoided. Thus,<br />

the applied action must always be known, i.e., >> and >>= are rigid in their arguments. Moreover,<br />

it is a runtime error if a disjunctive expression (cf. Section 3) σ1 e1 |· · ·| σn en, where the ei’s<br />

are of type IO () and n > 1, occurs as the top-level expression of a program, since it is unclear in<br />

this case which of the disjunctive actions should be applied to the current world. Thus, all possible<br />

search must be encapsulated between I/O operations (see Section 8).<br />

Using the evaluation annotations, a compiler is able to detect functions where search is definitely<br />

avoided (e.g., if all evaluated positions are declared as rigid). Thus, the compiler may warn the<br />

user about non-deterministic computations which may occur in I/O actions so that the programmer<br />

can encapsulate them.<br />

7.2 Do Notation<br />

To provide a more conventional notation for programming sequences of I/O operations, <strong>Curry</strong> has<br />

a special piece of syntax for writing such sequences. For instance, consider the following expression<br />

to read a line form the standard input and to print them together with the string "Your input: "<br />

on the standard output:<br />

getLine >>= \line -> putStr "Your input: " >> putStrLn line<br />

Using the do notation, this expression can be written in a more traditional style:<br />

28

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!