Haskell Variables

Why is the following Haskell script not working as expected?

find :: Eq a => a -> [(a,b)] -> [b] find kt = [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] . To obtain this information, you must enter a new variable below u :

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

Does anyone know why the first option does not give the desired result?

+5
source share
3 answers

From the Haskell 98 Report :

As usual, the bindings in the list comprehension can external areas; eg:

[ x | x <- x, x <- x ] = [ z | y <- x, z <- y]

Another point: if you compile -Wall (or specifically with -fwarn-name-shadowing ), you will receive the following warning:

 Warning: This binding for `k' shadows the existing binding bound at Shadowing.hs:4:5 

Using -Wall usually a good idea - it will often highlight what happens in potentially confusing situations like this.

+14
source

Matching the pattern (k,v) <- t in the first example creates two new local variables v and k filled with the contents of the tuple t . Matching the pattern does not compare the contents of t with the existing variable k , it creates a new variable k (which hides the external one).

As a rule, in a template there is never a β€œchange of variables”; any variable names in a template always create new local variables.

+11
source

You can map a pattern only to literals and constructors.
You cannot match variables. More details here .

In this case, you may be interested in viewing templates.

+3
source

Source: https://habr.com/ru/post/913342/


All Articles