Условие Haskell в функции отображения

#haskell #map

#haskell #словарь

Вопрос:

Возможно ли иметь условие в функции отображения?

Например :

 map (> 0 < 100 )[1..10]
  

Если это невозможно, как можно этого добиться?

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

1. Каким, по-вашему, должно быть значение этой формы?

Ответ №1:

Хороший способ выразить несколько условий фильтрации — для понимания, например

 [k | k <- [1..10], k > 2, k < 7]
  

Вы также можете избежать лямбда-выражения, используя Applicative , которое позволяет «передавать» один аргумент нескольким функциям:

 import Control.Applicative

filter ((amp;amp;) <$> (>2) <*> (<7)) [1..10]
  

Это может быть расширено для нескольких тестов следующим слегка загадочным способом:

 import Control.Applicative

filter (and . ([ (>2) , (<7) , odd ] <*>) . pure) [1..10]
  

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

[Править]

Если вы хотите покрасоваться, вы также можете использовать стрелки:

 import Control.Arrow

filter ((>2) amp;amp;amp; (<7) >>> uncurry (amp;amp;)) [1..10]
  

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

1. @Landei: вау! прекрасно! Я просто изучаю аппликативные функторы, и это отличные примеры! спасибо 🙂

2. @MarcoS: На самом деле это хорошее приложение и для стрелок, поэтому я добавил и эту версию. Но для приложений реального мира я бы счел как аппликативный, так и стрелочный синтаксис немного чрезмерным.

3. @Landei: Стрелки все еще находятся за пределами моего понимания, поэтому я не могу понять, что означает ваша последняя строка кода 🙂 В любом случае, спасибо, что указали на это: однажды я это пойму!

4.@Landei: Стрелки все еще находятся за пределами моего понимания, поэтому я не могу понять, что означает ваша последняя строка кода 🙂 В любом случае, спасибо, что указали на это: однажды я это пойму!

5. @MarcoS: Короткое, но очень интуитивно понятное введение en.wikibooks.org/wiki/Haskell/Understanding_arrows

Ответ №2:

Не совсем так, я полагаю, вы пытаетесь получить логическое значение, указывающее, больше ли значение 0 и меньше ли 100? У вас есть несколько вариантов:

Вы можете присвоить функции имя

 condition :: Int -> Bool
condition x = x > 0 amp;amp; x < 100
map condition [1..10]
  

Вы можете использовать лямбда

 map (x -> x > 0 amp;amp; x < 100) [1..10]
  

Вы можете использовать Data.Ix и inRange функцию

 import Data.Ix

-- inRange is inclusive.
map (inRange (1,99)) [1..10]
  

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

1. inRange проверяет только верхний предел ? :-S

2. Возмущение — это значения между двумя данными (то есть между 1 и 99 включительно). Я просто подумал, что это упростило логику >0 amp;amp; <100

3. на самом деле я решил проблему, написав свою собственную функцию inRange 😉 работает нормально !

Ответ №3:

map используется для сопоставления функции со списком. Если вы хотите отобразить функцию только на элементы списка, которые удовлетворяют условию, то вам, вероятно, следует использовать filter :

 map ( 2) $ filter (>0) [-10..120]
  

или, если у вас есть больше условий, которые должны выполняться все

 map ( 2) $ filter (>0) $ filter (<100) [-10..120]
  

или эквивалентно

 map ( 2) $ filter (x -> x>0 amp;amp; x<100) [-10..120]