В функциональном программировании функции не так сильно отличаются от чисел или любых других значений. На самом деле единственное отличие состоит в том, что вы используете функцию для применения к аргументу.
Значение типа Maybe a
является либо значением Nothing
, либо Just x
, где x
имеет тип a
. Поэтому, если у вас есть значение типа Maybe (a -> a)
, например, ваше foo
, это либо Nothing
, либо Just f
, где f
- это функция a -> a
. В наименьшей степени причудливой, вы бы использовали это так:
case foo of
Nothing -> "There was no function"
Just f -> "There was a function, and its value at 0 is " ++ show (f 0)
Так что, если окажется, что foo
не Nothing
, тогда он содержит Just
функцию в качестве значения.
@ Эрих прав, что особенно буквальное выражение f (a -> b)
может быть связано с аппликативными функторами, но это не обязательно так. Например, мой любимый тип - это тип изоморфизмов - эквивалентности между двумя типами:
data Iso a b = Iso (a -> b) (b -> a)
Iso
даже не Functor
(предварительное условие Applicative
), но это все еще весьма полезно. Оказывается, что пары эквивалентны функциям из Bool
. Мы могли бы построить такую эквивалентность как Iso
значение:
pairEquiv :: Iso (a,a) (Bool -> a)
pairEquiv =
Iso (\(x,y) -> \b -> if b then x else y) -- from pair to function
(\f -> (f True, f False)) -- from function to pair
Здесь (Bool -> a)
появляется в качестве аргумента для конструктора типа, и это просто означает, что если вы дадите Iso
пару, он вернет вам функцию, и наоборот.