Учебники

Haskell — Функтор

Функтор в Haskell является своего рода функциональным представлением различных типов, которые можно отобразить. Это концепция высокого уровня реализации полиморфизма. По словам разработчиков Haskell, все типы, такие как List, Map, Tree и т. Д., Являются экземпляром Haskell Functor.

Functor — это встроенный класс с определением функции, подобным —

class Functor f where 
   fmap :: (a -> b) -> f a -> f b 

Исходя из этого определения, мы можем заключить, что Functor является функцией, которая принимает функцию, скажем, fmap () и возвращает другую функцию. В приведенном выше примере fmap () является обобщенным представлением функции map () .

В следующем примере мы увидим, как работает Haskell Functor.

Live Demo

main = do  
   print(map (subtract 1) [2,4,8,16])      
   print(fmap (subtract 1) [2,4,8,16])   

Здесь мы использовали и map (), и fmap () над списком для операции вычитания. Вы можете заметить, что оба оператора приведут к одному и тому же результату списка, содержащего элементы [1,3,7,15].

Обе функции вызвали другую функцию subtract (), чтобы получить результат.

[1,3,7,15]
[1,3,7,15]

Тогда в чем разница между картой и fmap? Разница заключается в их использовании. Functor позволяет нам реализовать еще несколько функционалистов в разных типах данных, таких как «просто» и «ничего».

Live Demo

main = do 
   print (fmap  (+7)(Just 10)) 
   print (fmap  (+7) Nothing)

Приведенный выше фрагмент кода выдаст следующий вывод на терминал —

Just 17
Nothing

Аппликативный Функтор

Аппликативный функтор — это обычный функтор с некоторыми дополнительными функциями, предоставляемыми классом Applicative Type.

Используя Functor, мы обычно отображаем существующую функцию с другой функцией, определенной внутри нее. Но нет никакого способа сопоставить функцию, которая определена внутри Функтора, с другим Функтором. Вот почему у нас есть еще одно средство под названием Applicative Functor . Это средство отображения реализуется классом Applicative Type, определенным в модуле Control . Этот класс дает нам только два метода для работы: один — чистый, а другой — <*> .

Ниже приведено определение класса аппликативного функтора.

class (Functor f) => Applicative f where   
   pure :: a -> f a   
   (<*>) :: f (a -> b) -> f a -> f b   

В соответствии с реализацией мы можем отобразить другой Functor, используя два метода: «Pure» и «<*>» . Метод «Pure» должен принимать значение любого типа, и он всегда будет возвращать Applicative Functor этого значения.

В следующем примере показано, как работает Applicative Functor:

Live Demo

import Control.Applicative 

f1:: Int -> Int -> Int 
f1 x y = 2*x+y  
main = do  
   print(show $ f1 <$> (Just 1) <*> (Just 2) ) 

Здесь мы реализовали аппликативные функторы в вызове функции f1 . Наша программа даст следующий результат.

"Just 4"

Моноиды

Мы все знаем, что Хаскелл определяет все в форме функций. В функциях у нас есть опции для получения нашего ввода в качестве выхода функции. Вот что такое моноид .

Monoid — это набор функций и операторов, в которых выходные данные не зависят от его входных данных. Давайте возьмем функцию (*) и целое число (1). Теперь, каким бы ни был ввод, его вывод останется только тем же номером. То есть, если вы умножите число на 1, вы получите тот же номер.

Вот определение класса класса моноида.

class Monoid m where  
   mempty :: m 
   mappend :: m -> m -> m  
   mconcat :: [m] -> m 
   mconcat = foldr mappend mempty 

Посмотрите на следующий пример, чтобы понять использование Monoid в Haskell.

Live Demo

multi:: Int->Int 
multi x = x * 1 
add :: Int->Int 
add x = x + 0 

main = do  
   print(multi 9)  
   print (add 7)

Наш код выдаст следующий результат:

9
7

Здесь функция «multi» умножает ввод на «1». Точно так же функция «добавить» добавляет ввод с «0». В обоих случаях вывод будет таким же, как и ввод. Следовательно, функции {(*), 1} и {(+), 0} являются прекрасными примерами моноидов.