Переменные в Хаскеле - PullRequest
       0

Переменные в Хаскеле

5 голосов
/ 29 октября 2010

Почему следующий скрипт на Haskell не работает должным образом?

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

Если задано find 'b' [('a',1),('b',2),('c',3),('b',4)], интерпретатор возвращает [1,2,3,4] вместо [2,4].Чтобы это заработало, необходимо ввести новую переменную, называемую ниже u:

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

Кто-нибудь знает, почему первый вариант не дает желаемого результата?

Ответы [ 3 ]

14 голосов
/ 29 октября 2010

Из отчета на Haskell 98 :

Как обычно, привязки в представлениях списков могут скрывать привязки во внешних областях;например:

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

Еще один момент: если вы скомпилируете с -Wall (или конкретно с -fwarn-name-shadowing), вы получитеследующее предупреждение:

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

Использование -Wall обычно является хорошей идеей - оно часто освещает то, что происходит в потенциально запутанных ситуациях, подобных этой.

11 голосов
/ 29 октября 2010

В соответствии с шаблоном (k,v) <- t в первом примере создаются две новые локальные переменные v и k, которые заполняются содержимым кортежа t. Сопоставление с шаблоном не сравнивает содержимое t с уже существующей переменной k, оно создает новую переменную k (которая скрывает внешнюю).

Обычно в шаблоне никогда не происходит "подстановки переменных", любые имена переменных в шаблоне всегда создают новые локальные переменные.

3 голосов
/ 29 октября 2010

Вы можете сопоставлять шаблоны только с литералами и конструкторами.
Вы не можете соответствовать по переменным. Подробнее здесь .

Как говорится, вас могут заинтересовать шаблоны представлений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...