Curry: An Integrated Functional Logic Language
Curry: An Integrated Functional Logic Language
Curry: An Integrated Functional Logic Language
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