📅  最后修改于: 2020-11-04 07:00:41             🧑  作者: Mango
Haskell中的Functor是一种可以映射的不同类型的功能表示。这是实现多态性的高级概念。根据Haskell开发人员的说法,所有类型(例如List,Map,Tree等)都是Haskell Functor的实例。
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]的列表的相同结果。
这两个函数都调用了另一个称为减法()的函数来产生结果。
[1,3,7,15]
[1,3,7,15]
那么, map和fmap有什么区别?不同之处在于它们的用法。 Functor使我们能够在不同的数据类型中实现更多的功能主义者,例如“ just”和“ Nothing”。
main = do
print (fmap (+7)(Just 10))
print (fmap (+7) Nothing)
上面的代码将在终端上产生以下输出:
Just 17
Nothing
Applicative Functor是一个普通的Functor,具有Applicative Type类提供的一些额外功能。
使用Functor,我们通常将现有函数与内部定义的另一个函数映射。但是,没有任何一种方法来映射它与另一个函子仿函数中定义的函数。这就是为什么我们拥有另一个名为Applicative Functor的设施的原因。这种映射功能由“控制”模块下定义的“应用类型”类实现。此类仅提供两种方法供您使用:一种是纯方法,另一种是<*> 。
以下是应用函子的类定义。
class (Functor f) => Applicative f where
pure :: a -> f a
() :: f (a -> b) -> f a -> f b
根据实现,我们可以使用两种方法映射另一个Functor: “ 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"
众所周知,Haskell以函数形式定义了所有内容。在函数中,我们可以选择将输入作为函数的输出。这就是Monoid 。
Monoid是一组函数和运算符,其中输出与其输入无关。让我们考虑一个函数(*)和一个整数(1)。现在,无论输入是什么,其输出将仅保持相同的数字。也就是说,如果将数字乘以1,将得到相同的数字。
这是Monoid的类型类定义。
class Monoid m where
mempty :: m
mappend :: m -> m -> m
mconcat :: [m] -> m
mconcat = foldr mappend mempty
请看以下示例,以了解Haskell中Monoid的用法。
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的完美示例。