ТОП 10:

Использование аппликативных функторов



В этом разделе мы рассмотрим аппликативные функторы, ко- торые являются расширенны- ми функторами.

До настоящего времени мы были сосредоточены на отобра- жении функторов с помощью функций, принимающих толь- ко один параметр. Но что про- исходит, когда мы отображаем функтор с помощью функции, которая принимает два пара- метра? Давайте рассмотрим пару конкретных примеров.

Если у нас есть Just 3, и мы выполняем выражение fmap (*) (Just 3), что мы получим? Из реализации экземпляра типа Maybe для класса Functor мы знаем, что если это значение Just, то функция будет применена к значению внутри Just. Следовательно, выполне- ние выражения fmap (*) (Just 3) вернёт Just ((*) 3), что может быть также записано в виде Just (3 *), если мы используем сечения. Ин- тересно! Мы получаем функцию, обёрнутую в конструктор Just!

 
 

Вот ещё несколько функций внутри значений функторов:

ghci> :t fmap (++) (Just "эй")

fmap (++) (Just "эй") :: Maybe ([Char] –> [Char])


 

ghci> :t fmap compare (Just 'a')

fmap compare (Just 'a') :: Maybe (Char –> Ordering) ghci> :t fmap compare "A LIST OF CHARS"

fmap compare "A LIST OF CHARS" :: [Char –> Ordering] ghci> :t fmap (\x y z –> x + y / z) [3,4,5,6]

 
 

fmap (\x y z –> x + y / z) [3,4,5,6] :: (Fractional a) => [a –> a –> a]

Если мы отображаем список символов с помощью функции compare, которая имеет тип (Ord a) => a –> a –> Ordering, то получаем список функций типа Char –> Ordering, потому что функция compare частично применяется с помощью символов в списке. Это не спи- сок функций типа (Ord a) => a –> Ordering, так как первый идентифи- катор переменной типа a имел тип Char, а потому и второе вхожде- ние a обязано принять то же самое значение – тип Char.

Мы видим, как, отображая значения функторов с помощью

 
 

«многопараметрических» функций, мы получаем значения фун- кторов, которые содержат внутри себя функции. А что теперь с ними делать?.. Мы можем, например, отображать их с помощью функций, которые принимают эти функции в качестве парамет- ров – поскольку, что бы ни находилось в значении функтора, оно будет передано функции, с помощью которой мы его отображаем, в качестве параметра.

ghci> let a = fmap (*) [1,2,3,4] ghci> :t a

 
 

a :: [Integer –> Integer] ghci> fmap (\f –> f 9) a [9,18,27,36]

Но что если у нас есть значение функтора Just (3 *) и значе- ние функтора Just 5, и мы хотим извлечь функцию из Just (3 *) и отобразить с её помощью Just 5? С обычными функторами у нас этого не получится, потому что они поддерживают только отобра- жение имеющихся функторов с помощью обычных функций. Даже когда мы отображали функтор, содержащий функции, с помощью анонимной функции \f –> f 9, мы делали именно это и только это. Но используя то, что предлагает нам функция fmap, мы не можем с помощью функции, которая находится внутри значения функтора, отобразить другое значение функтора. Мы могли бы произвести со- поставление конструктора Just по образцу для извлечения из него


 

функции, а затем отобразить с её помощью Just 5, но мы ищем бо- лее общий и абстрактный подход, работающий с функторами.

 







Последнее изменение этой страницы: 2017-02-17; Нарушение авторского права страницы

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.235.29.190 (0.005 с.)