должно быть эквивалентно выражению
>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
Мы не будем рассматривать их подробно, потому что это заняло бы много страниц и было бы несколько скучно. Если вам интересно, вы можете познакомиться с этими законами поближе и посмотреть, выполняются ли они для некоторых экземпляров.