Curry: An Integrated Functional Logic Language
Curry: An Integrated Functional Logic Language
Curry: An Integrated Functional Logic Language
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
that functions have to be evaluated in a strict manner but this behavior can be easily obtained by<br />
sharing the different occurrences of a variable.<br />
Since different occurrences of the same variable are always shared but different occurrences of<br />
(textually identical) function calls are not shared, it is important to distinguish between variables<br />
and functions. Usually, all symbols occurring at the top-level in the left-hand side of some rule are<br />
considered as functions and the non-constructor symbols in the arguments of the left-hand sides<br />
are considered as variables. But note that there is a small exception from this general rule in local<br />
declarations (see Section 2.4).<br />
2.3.2 Conditional Equations with Boolean Guards<br />
For convenience and compatibility with Haskell, one can also write conditional equations with<br />
multiple guards<br />
f t1 . . . tn | b1 = e1<br />
.<br />
| bk = ek<br />
where b1, . . . , bk (k > 0) are expressions of type Bool. Such a rule is interpreted as in Haskell:<br />
the guards are successively evaluated and the right-hand side of the first guard which is evaluated<br />
to True is the result of applying this equation. Thus, this equation can be considered as an<br />
abbreviation for the rule<br />
f t1 . . . tn = if b1 then e1 else<br />
.<br />
if bk then ek else undefined<br />
(where undefined is some non-reducible function). To write rules with several Boolean guards<br />
more nicely, there is a Boolean function otherwise which is predefined as True. For instance, the<br />
factorial function can be declared as follows:<br />
fac n | n==0 = 1<br />
| otherwise = fac(n-1)*n<br />
Since all guards have type Bool, this definition is equivalent to (after a simple optimization)<br />
fac n = if n==0 then 1 else fac(n-1)*n<br />
To avoid confusion, it is not allowed to mix the Haskell-like notation with Boolean guards and the<br />
standard notation with constraints: in a rule with multiple guards, all guards must be expressions<br />
of type Bool. The default type of a guard in single-guarded rules is Success, i.e., in a rule like<br />
f c x | c = x<br />
the type of the variable c is Success (provided that it is not restricted to Bool by the use of f).<br />
2.4 Local Declarations<br />
Since not all auxiliary functions should be globally visible, it is possible to restrict the scope of<br />
declared entities. Note that the scope of parameters in function definitions is already restricted<br />
7