Изучай Haskell во имя добра! (Липовача) - страница 193

должно быть эквивалентно выражению >fmap f xs. Если бы вызов выражения >pure 3 просто вернул >ZipList [3], вызов >pure (*2) <*> ZipList [1,5,10] дал бы в результате >ZipList [2], потому что длина результирующего списка из двух застёгнутых списков равна длине более короткого списка из двух. Если мы застегнём конечный список с бесконечным, длина результирующего списка всегда будет равна длине конечного списка.

Так как же застёгиваемые списки работают в аппликативном стиле? Давайте посмотрим.

Ладно, тип >ZipList a не имеет экземпляра класса >Show, поэтому мы должны использовать функцию >getZipList для извлечения обычного списка из застёгиваемого:

>ghci> getZipList $ (+) <$> ZipList [1,2,3] <*> ZipList [100,100,100]

>[101,102,103]

>ghci> getZipList $ (+) <$> ZipList [1,2,3] <*> ZipList [100,100..]

>[101,102,103]

>ghci> getZipList $ max <$> ZipList [1,2,3,4,5,3] <*> ZipList [5,3,1,2]

>[5,3,3,4]

>ghci> getZipList $ (,,) <$> ZipList "пар" <*> ZipList "ток" <*> ZipList "вид"

>[('п','т','в'),('а','о','и'),('р',кt','д')]

ПРИМЕЧАНИЕ. Функция >(,,) – это то же самое, что и анонимная функция >\x y z –> (x,y,z). В свою очередь, функция >(,) – то же самое, что и >\x y –> (x,y).

Помимо функции >zipWith в стандартной библиотеке есть такие функции, как >zipWith3, >zipWith4, вплоть до >7. Функция >zipWith берёт функцию, которая принимает два параметра, и застёгивает с её помощью два списка. Функция >zipWith3 берёт функцию, которая принимает три параметра, и застёгивает с её помощью три списка, и т. д. При использовании застёгиваемых списков в аппликативном стиле нам не нужно иметь отдельную функцию застёгивания для каждого числа списков, которые мы хотим застегнуть друг с другом. Мы просто используем аппликативный стиль для застёгивания произвольного количества списков при помощи функции, и это очень удобно.

Аппликативные законы

Как и в отношении обычных функторов, применительно к аппликативным функторам действует несколько законов. Самый главный состоит в том, чтобы выполнялось тождество >pure f <*> x = fmap f x. В качестве упражнения можете доказать выполнение этого закона для некоторых аппликативных функторов из этой главы. Ниже перечислены другие аппликативные законы:

• >pure id><*>>v>=>v

• >pure>(.)><*>>u><*>>v><*>>w>=>u><*>>(v><*>>w)

• >pure>f><*>>pure>x>=>pure>(f>x)

• >u><*>>pure>y>=>pure>($>y)><*>>u

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

Полезные функции для работы с аппликативными функторами