Замыкания и списки в Хаскеле - PullRequest
6 голосов
/ 04 октября 2011

Я сейчас играю с Haskell и, таким образом, наткнулся на функцию понимания списка.Естественно, я бы использовал замыкание для такого рода вещей:

Prelude> [x|x<-[1..7],x>4] -- list comprehension
[5,6,7]
Prelude> filter (\x->x>4) [1..7] -- closure
[5,6,7]

Я до сих пор не чувствую этот язык, так в каком направлении пойдет программист на Haskell?Каковы различия между этими двумя решениями?

Ответы [ 2 ]

10 голосов
/ 04 октября 2011

Идиоматический Haskell будет filter (> 4) [1..7]

Обратите внимание, что вы не захватываете какую-либо лексическую область в вашем закрытии, а вместо этого используете оператор секционирования. Другими словами, вы хотите частичное применение >, которое вам сразу дают разделы оператора. Понимания списков иногда привлекательны, но обычное восприятие состоит в том, что они не так хорошо масштабируются, как обычный набор функций более высокого порядка («масштаб» в отношении более сложных композиций). Такое стилистическое решение, конечно, в значительной степени субъективно, поэтому YMMV.

1 голос
/ 04 октября 2011

Понятия списка полезны, если элементы несколько сложны, и нужно отфильтровать их по сопоставлению с образцом, или часть отображения чувствует себя слишком сложной для лямбда-абстракции, которая должна быть короткой (или я так чувствую), или если одинимеет дело с вложенными списками.В последнем случае понимание списка часто более читабельно, чем альтернативы (для меня, во всяком случае).

Например, что-то вроде:

[ (f b, (g . fst) a) | (Just a, Right bs) <- somelist, a `notElem` bs, (_, b) <- bs ]

Но для вашего примера, раздел (>4) - это действительно хороший способ написать (\a -> a > 4), и поскольку вы используете его только для фильтрации, большинство людей предпочли бы решение ANthonys.

...