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".
|