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