95 lines
3.2 KiB
Markdown
95 lines
3.2 KiB
Markdown
|
+++
|
|||
|
title = "Value definitions"
|
|||
|
weight = 1
|
|||
|
+++
|
|||
|
|
|||
|
A value definition defines the value of an identifier (which could be a
|
|||
|
function). Value definitions are the meat of a BH program.
|
|||
|
|
|||
|
Value definitions consist of a type signature followed immediately by
|
|||
|
one or more defining clauses:
|
|||
|
|
|||
|
```
|
|||
|
topDefn ::= valueDefn
|
|||
|
valueDefn ::= varId :: ctxType ;
|
|||
|
{clause ; }
|
|||
|
clause ::= varId
|
|||
|
{apat }[ when guard ]= exp
|
|||
|
```
|
|||
|
|
|||
|
The first line of a value definition is the type signature--- it simply
|
|||
|
specifies that the identifier *varId* has the type *ctxType*. Subsequent
|
|||
|
lines define the value, one clause at a time. The *varId*'s on the
|
|||
|
left-hand side of the type signature and on the left-hand side of each
|
|||
|
clause must all be the same, *i.e.,* they collectively define a single
|
|||
|
*varId*.
|
|||
|
|
|||
|
Each clause defines part of the value, using pattern matching and
|
|||
|
guards. If there are patterns (*apat*'s) present, then the *varId* being
|
|||
|
defined is a function, and the patterns represent arguments to the
|
|||
|
function. The *guard* is a list of arbitrary predicates that may use
|
|||
|
identifiers bound in the patterns (see Section [7](fixme)).
|
|||
|
|
|||
|
The clause should be read as follows: if the function *varId* is applied to
|
|||
|
arguments that match the corresponding *apat*'s (in which case,
|
|||
|
identifiers in the *apat*'s are bound to the corresponding components of
|
|||
|
the arguments), and if the predicates in the *guard* are true, then the
|
|||
|
function returns the value of the expression *exp*.
|
|||
|
|
|||
|
Example:
|
|||
|
|
|||
|
```hs
|
|||
|
wordSize :: Integer
|
|||
|
wordSize = 16
|
|||
|
```
|
|||
|
|
|||
|
|
|||
|
This simply defines the identifier `wordSize` to have type `Integer` and
|
|||
|
value 16.
|
|||
|
|
|||
|
|
|||
|
Example:
|
|||
|
|
|||
|
```hs
|
|||
|
not :: Bool -> Bool
|
|||
|
not True = False
|
|||
|
not False = True
|
|||
|
```
|
|||
|
|
|||
|
This defines the classical Boolean negation function. The type signature
|
|||
|
specifies that `not` is a function with argument type `Bool` and result
|
|||
|
type `Bool`. After that, the first clause specifies that if the argument
|
|||
|
matches the value `True` (*i.e.,* it *is* the value `True`), then it
|
|||
|
returns `False`. The final clause specifies that if the argument is
|
|||
|
`False` it returns `True`.
|
|||
|
|
|||
|
|
|||
|
Example:
|
|||
|
|
|||
|
```hs
|
|||
|
f :: Maybe Int -> Int -> Int
|
|||
|
f (Just x) y when x > 10, Just y’ <- g y = x + y'
|
|||
|
f _ _ = 0
|
|||
|
```
|
|||
|
|
|||
|
(If necessary, please first remember the definition of the `Maybe` type,
|
|||
|
introduced in section [4.1](fixme)). The first line specifies that
|
|||
|
`f` is a function
|
|||
|
of two arguments, of type `Maybe Int` and `Int`, respectively, and that
|
|||
|
its result has type `Int`. The second line specifies that if the first
|
|||
|
argument has the form `Just x` (in which case let us call its component
|
|||
|
`x`), if the second argument is anything (let us call it `y`), if `x`'s
|
|||
|
value is greater than 10, if the result of applying `g` to `y` has the
|
|||
|
form `Just y’` (in which case let us call the component `y’`), then the
|
|||
|
result is the value of `x + y’`. In all other cases, the result is the
|
|||
|
value 0. The bare underscores in the second line are *wild-card*
|
|||
|
patterns that match anything (described in section
|
|||
|
[6.1](fixme)).
|
|||
|
|
|||
|
|
|||
|
Clauses are attempted in order, from top to bottom, proceeding to the
|
|||
|
next clause only if the pattern matching and guard evaluation fail.
|
|||
|
Within each clause, pattern matching and guard evaluation are attempted
|
|||
|
from left to right. If no clause succeeds, then the system will raise a
|
|||
|
"pattern matching error".
|