Haskell: Область действия переменной при использовании лямбда-выражения с функциями связывания - PullRequest
4 голосов
/ 20 августа 2010

Следующая строка работает, как и ожидалось, но меня немного беспокоит, почему:

getLine >>= \x-> getLine >>= \y-> return [x, y]

Рассмотрим добавление скобок в область видимости лямбда-выражений:

getLine >>= (\x-> getLine) >>= (\y-> return [x, y])

Вторая строка ошибочна, потому что x не входит в область при использовании в return, и я счастлив с этим Что меня касается, так это то, что в первой строке область действия x, похоже, «просочилась».

Эта утечка считается плохой практикой? Я смущен тем, как он остался в области видимости и не был потерян сразу после выражения \x -> getLine.

Ответы [ 4 ]

14 голосов
/ 20 августа 2010

Если вы правильно заключите в скобки первую строку в соответствии с правилами приоритета haskell, вы получите:

getLine >>= (\x-> getLine >>= (\y-> return [x, y]))

Это делает очевидным, что вторая лямбда находится внутри первой, поэтому нет проблем с доступом к переменнымпервой лямбды.

12 голосов
/ 20 августа 2010

Ваши круглые скобки просто установлены неправильно.Правильные скобки:

getLine >>= (\x -> getLine >>= (\y -> return [x, y]))

И, следовательно, x определено в теле.

Обратите внимание, что эта функция особенно полезна, поскольку вы можете форматировать код следующим образом:

getLine >>= \x ->
getLine >>= \y ->
return [x, y]

, что почти

do
  x <- getLine
  y <- getLine
  return [x, y]

, но без какого-либо специального синтаксиса.

2 голосов
/ 22 августа 2010

Синтаксис Haskell следует правилу «максимального мунка»: каждый элемент синтаксиса расширяется настолько, насколько это возможно, пока его дальнейшее расширение не приведет к ошибке. Так как он прекрасно работает, расширяя область действия «\x ->» до самого конца, это то, что он делает.

1 голос
/ 20 августа 2010

Ссылка на x в выражении return известна как замыкание .Это типичная особенность функциональных языков программирования.В чистом функциональном языке программирования, таком как Haskell, нет причин для беспокойства.Это очень хорошая особенность.В «гибридных» функциональных языках программирования, таких как F # (и C # в наши дни), замыкания могут иногда приводить к неожиданному поведению.

...