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

мы знаем, что если это значение >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, но мы ищем более общий и абстрактный подход, работающий с функторами.

Поприветствуйте аппликативные функторы