Haskell - Functor

Haskell 中的 Functor 是一种可以映射的不同类型的函数表示。 它是实现多态性的高级概念。 根据 Haskell 开发人员的说法,所有类型(例如 List、Map、Tree 等)都是 Haskell Functor 的实例。

A Functor 是一个内置类,其函数定义如下 −

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

根据这个定义,我们可以得出结论,Functor 是一个函数,它接受一个函数,例如 fmap() 并返回另一个函数。 在上面的例子中,fmap()是函数map()的通用表示。

在下面的示例中,我们将了解 Haskell Functor 的工作原理。

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]

那么,mapfmap?有什么区别呢?区别就在于它们的用法。 Functor 使我们能够在不同的数据类型中实现更多的功能主义,例如"just"和"Nothing"。

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

上面的代码将在终端上产生以下输出 −

Just 17
Nothing

Applicative Functor

Applicative Functor 是一个普通的 Functor,具有 Applicative Type Class 提供的一些额外功能。

使用 Functor,我们通常将现有函数与其中定义的另一个函数进行映射。 但是没有任何方法可以将一个 Functor 内部定义的函数与另一个 Functor 进行映射。 这就是为什么我们有另一个名为Applicative Functor的工具。 这种映射功能是由 Control 模块下定义的 Applicative Type 类实现的。 这个类只给我们提供了两种方法:一种是pure,另一种是<*>

以下是 Applicative Functor 的类定义。

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

根据实现,我们可以使用两种方法映射另一个Functor:"Pure""<*>"。 "Pure"方法应该采用任何类型的值,并且它将始终返回该值的应用函子。

以下示例显示了应用函子的工作原理 −

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

我们都知道 Haskell 以函数的形式定义了一切。 在函数中,我们可以选择将输入作为函数的输出。 这就是 Monoid

Monoid 是一组函数和运算符,其输出与其输入无关。 让我们采用一个函数 (*) 和一个整数 (1)。 现在,无论输入是什么,其输出都将仅保持相同的数字。 也就是说,如果将一个数字乘以 1,您将得到相同的数字。

这里是 monoid 的类型类定义。

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

看下面的例子来了解 Monoid 在 Haskell 中的使用。

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"相乘。 类似地,函数"add"将输入添加"0"。 在这两种情况下,输出将与输入相同。 因此,函数 {(*),1}{(+),0} 是 Monoid 的完美示例。