elem [1..10]
- совершенно разумный термин. Пример:
Prelude> elem [1..10] [[0..9], [1..10]]
True
Prelude> elem [1..10] [[0..8], [1..7]]
False
Возможно, чаще всего это будет написано
Prelude> [1..10] `elem` [[0..9], [1..10]]
True
Prelude> [1..10] `elem` [[0..8], [1..7]]
False
, но это просто другая версия syntacti c той же вещи.
Это означает также, что можно скомпилировать, вам просто нужно дать ему соответствующую подпись (или попросить GH C сделать ее для вас). Например,
f :: [[Int]] -> Bool
f = elem [1..10]
... это функция, которая сообщает, содержит ли список числовых списков список [1..10]
. То есть, как и при любом другом использовании elem
, он сообщает вам, содержит ли какой-либо список элемент. Тот факт, что этот элемент сам по себе является списком, не имеет значения.
С другой стороны, map [1..10]
просто неверен, поскольку первым аргументом map
должна быть функция . И списки, хотя они могут быть элементами списков, никогда не могут быть функциями † .
Это совсем другая история с разделами оператора (`elem`[1..10])
и (`map`[1..10])
. В этих примерах [1..10]
на самом деле является аргументом second . В этом разделе пропущен левый / первый аргумент. Таким образом, в данном случае мы говорим о
Prelude> 3 `elem` [1..10]
True
Prelude> 19 `elem` [1..10]
False
... и это также работает с
Prelude> negate `map` [1..10]
[-1,-2,-3,-4,-5,-6,-7,-8,-9,-10]
, хотя это будет более обычно написано map negate [1..10]
или negate<$>[1..10]
.
† В некотором смысле это одновременно pedanti c и anarchi c, списки могут фактически быть функциями: с расширение -XOverloadedLists
, вы можете написать экземпляр класса, который позволит вам определять функции, используя синтаксис списка. Я не понимаю, как это могло бы иметь какой-то смысл, но, может быть, хорошо осознавать эту теоретическую возможность. В частности, с этим включенным расширением map [1..10]
сбивает с толку компилирует , и вы просто получаете сбивающую с толку ошибку, связанную с Could not deduce
... The type variable ‘a0’ is ambiguous
gibberi sh в другом месте.