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]的列表的相同结果.
这两个函数都称为另一个函数减去()得出结果.
[1,3,7,15]
[1,3, 7,15]
那么,地图与 fmap有什么区别?区别在于在他们的用法. Functor 使我们能够在不同的数据类型中实现更多功能主义者,例如"just"和"Nothing".
main = do
print (fmap (+7)(Just 10))
print (fmap (+7) Nothing)
上面的代码将在终端上产生以下输出 :
Just 17
Nothing
Applicative Functor
Applicative Functor是一个普通的Functor,具有应用类型类提供的一些额外功能.
使用Functor,我们通常将现有函数映射到其中定义的另一个函数.但是没有任何方法可以将Functor中定义的函数映射到另一个Functor.这就是为什么我们有另一个名为 Applicative Functor 的设施.这种映射工具由 Control 模块下定义的Applicative Type类实现.这个类只给我们两种方法:一个是纯,另一个是< *> .
以下是Applicative Functor的类定义.
class (Functor f) => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
根据实施,我们可以使用两种方法映射另一个Functor:"Pure"和"< *>"中的. "Pure"方法应该采用任何类型的值,并且它将始终返回该值的Applicative Functor.
以下示例显示了Applicative Functor如何工作 :
import Control.Applicative
f1:: Int -> Int -> Int
f1 x y = 2*x+y
main = do
print(show $ f1 <$> (Just 1) <*> (Just 2) )
这里,我们在函数 f1 的函数调用中实现了applicative仿函数.我们的程序将产生以下输出.
"Just 4"
Monoids
我们都知道Haskell以函数的形式定义了所有东西.在函数中,我们可以选择将输入作为函数的输出.这就是 Monoid 的原因.
A Monoid 是一组函数和运算符,其输出独立于其输入.我们取一个函数(*)和一个整数(1).现在,无论输入是什么,其输出将仅保持相同的数字.也就是说,如果你将数字乘以1,你将获得相同的数字.
这是monoid的Type Class定义.
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} 是幺半群的完美例子.