Реализация функции длины в нотации zf

#haskell

#haskell

Вопрос:

Как я могу реализовать функцию длины в Haskell, используя понимание списка? Пример.

 take [x| x<- [1,2,3], even]
 

Комментарии:

1. Что такое ‘обозначение zf’? Это, конечно, не тот термин, о котором я знаю. Кроме того, имеет ли ваш пример кода какое-либо отношение к вашему вопросу?

2. Вы не можете реализовать length функцию, используя понимание списка. Понимание списка может создать только список!

3. @bradrn, может быть, это относится к сходству между нотацией для понимания списков и пониманием множеств в (например, в теории множеств Цермело-Френкеля)?

4. @dfeuer Вы могли бы сделать что-то хакерское -XParallelListComp ? Но да, это не то, что вы можете сделать в ‘традиционном’ понимании списков.

5. [ () | _ <- xs ] возвращает длину списка в унарной записи . Так же [ x | x <- xs ] , как и or просто xs .

Ответ №1:

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

 length x =
  sum [ 1 | _ <- x ]
 

Это заменяет каждый элемент в списке на 1 , а затем принимает сумму.

Еще один несколько прямой способ сделать это:

 length x =
  last [ i | (_, i) <- zip (undefined : x) [0 ..] ]
 

Здесь мы расширяем список на 1, заменяем каждый элемент в списке его индексом, используя понимание списка, и берем последний индекс. Вы также можете заменить maximum вместо last , и это будет работать.

Есть и гораздо более экзотические способы, о которых можно пофантазировать

 length x =
  foldr ($) 0 [ ( 1) | _ <- x ]
 

но их слишком много, чтобы я мог перечислить.

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