Why does the following Haskell script not work as expected?
find :: Eq a => a -> [(a,b)] -> [b]
find k t = [v | (k,v) <- t]
Giv
You can only pattern match on literals and constructors.
You can't match on variables.
Read more here.
That being said, you may be interested in view patterns.
From the Haskell 98 Report:
As usual, bindings in list comprehensions can shadow those in outer scopes; for example:
[ x | x <- x, x <- x ] = [ z | y <- x, z <- y]
One other point: if you compile with -Wall
(or specifically with -fwarn-name-shadowing) you'll get the following warning:
Warning: This binding for `k' shadows the existing binding
bound at Shadowing.hs:4:5
Using -Wall
is usually a good idea—it will often highlight what's going on in potentially confusing situations like this.
The pattern match (k,v) <- t
in the first example creates two new local variables v
and k
that are populated with the contents of the tuple t
. The pattern match doesn't compare the contents of t
against the already existing variable k
, it creates a new variable k
(which hides the outer one).
Generally there is never any "variable substitution" happening in a pattern, any variable names in a pattern always create new local variables.