Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Variables in Haskell

Why does the following Haskell script not work as expected?

find :: Eq a => a -> [(a,b)] -> [b]
find k t = [v | (k,v) <- t]

Given find 'b' [('a',1),('b',2),('c',3),('b',4)], the interpreter returns [1,2,3,4] instead of [2,4]. The introduction of a new variable, below called u, is necessary to get this to work:

find :: Eq a => a -> [(a,b)] -> [b]
find k t = [v | (u,v) <- t, k == u]

Does anyone know why the first variant does not produce the desired result?

like image 923
sentinel Avatar asked Oct 29 '10 16:10

sentinel


People also ask

Does Haskell have global variables?

So, in particular, all those tasks which you use global variables for in C, can be achieved in haskell, but which solution depends what you are trying to do: If you have some globals which are constant, then just define them at the top level.

How do I change the value of a variable in Haskell?

You can't. Once a variable has a value, it has that value forever.

What does ++ mean in Haskell?

The ++ operator is the list concatenation operator which takes two lists as operands and "combines" them into a single list.

What does variable not in scope mean in Haskell?

(When GHC complains that a variable or function is "not in scope," it simply means that it has not yet seen a definition of it yet. As was mentioned before, GHC requires that variables and functions be defined before they are used.)


2 Answers

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.

like image 131
Travis Brown Avatar answered Oct 01 '22 01:10

Travis Brown


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.

like image 32
sth Avatar answered Oct 01 '22 01:10

sth