( ), , " " , Haskell . , (.. "" ):
func x = foo i j k
where
foo i j k = i + j + k
k = bat x
j = baz k
i = bar j
, , func 10
. ?
, :
- (, ,
x
k
x
func x
..) - " ", Haskell, , .
, where
, , where
"" - where
func x
. where
:
-, , ( func
) ( x
). func
x
where
func
x
func x
, ( , where
func
x
, "" - ). , x
k = bat x
x
func x
.
-, , where
( foo
, k
, j
i
), , i
, j
k
foo i j k
NOT , -Wall
. - :
func x = foo i j k
where
foo i' j' k' = i' + j' + k'
k = bat x
j = baz k
i = bar j
. , k
in j = baz k
k
, k = bat x
, j
in i = bar j
j
, j = baz k
, i
, j
k
, where
, i'
, j'
k'
foo i' j' k'
. , . :
func x = foo i j k
where
foo i' j' k' = i' + j' + k'
i = bar j
j = baz k
k = bat x
. , i = bar j
j
, - j
.
-, where
, . func x = foo i j k
foo
, k
, j
i
. ( , , - - where
func
x
, , , -Wall
, .)
, :
func x = foo i j k
where
foo i' j' k' = i' + j' + k'
k = bat x
j = baz k
i = bar j
(, k
).
Now the link transparency rule comes into effect. You can determine the meaning of an expression by replacing any name by its definition (trying to avoid name collisions or the so-called “capture” of names). Therefore, if we were to evaluate func 10
, it would be tantamount to:
func 10 -- binds x to 10
= foo i j k -- by defn of func
at this stage, a definition is used foo
that associates i'
with i
, j'
with j
and k'
to k
, to obtain the expression:
= i + j + k -- by defn of foo
= bar j + baz k + bat x -- by defs of i, j, k
= bar (baz k) + baz k + bat x -- by defn of j
= bar (baz (bat x)) + baz (bat x) + bat x -- by defn of k
= bar (baz (bat 10)) + baz (bat 10) + bat 10 -- by defn of x
So, if we determined:
bat = negate
baz y = 7 + y
bar z = 2*z
then we expect:
func 10 = 2 * (7 + negate 10) + (7 + negate 10) + negate 10
= -19
what we get:
> func 10
-19