符号<$>
和<*>
的含义是什么?
另外,我找到了一些有关<$
和$>
的信息。
答案 0 :(得分:7)
这些运算符在Control.Applicative
中定义。 <$>
运算符只是fmap
的中缀版本:
f <$> a = fmap f a
<*>
是Applicative
类型类定义的一部分:
class Functor f => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
您可以使用hoogle更轻松地搜索Haskell函数和运算符。
Applicative
类型类介于Functor
和Monad
之间:
class Functor where ...
class Functor f => Applicative f where ...
class Applicative m => Monad m where ...
(请注意,这是Applicative
和Monad
之间的关系,仅在最近发布的GHC 7.10中强制执行。
申请人是遵循特定规则的结构。它比一个仿函数更强大但比一个monad更强大。具体而言,仿函数只能将单参数函数应用于结构中的值,返回包含新值但不包含新形状的新结构。规范示例为fmap (+1) [1,2,3] == [2,3,4]
,输入列表的长度始终与输出列表相同。使用applicatives,您可以跨多个结构应用多参数纯函数:
> (+) <$> [1, 2, 3] <*> [10, 20]
[11, 21, 12, 22, 13, 23]
输出列表的长度(&#34;形状&#34;)取决于输入列表的长度。但是,需要注意的是输出列表的长度不依赖于列表中的值。这是monad添加到此层次结构的强大功能:
> print $ do a <- [1, 2, 3]; b <- replicate a 10; return (a + b)
[11, 12, 12, 13, 13, 13]
这里我们将两个结构组合在一起,其中一个具有&#34;形状&#34;这取决于另一个的价值。只有应用程序才能实现这一点,这就是为什么monads在Haskell中如此普遍存在的原因。但是,由于每个Monad
都是Applicative
,每Applicative
个Functor
,因此在使用Monad
时,您仍然可以访问所有这些工具。
答案 1 :(得分:4)
<$>
是fmap的同义词,<$>
是中缀运算符。它通常用于应用函子的上下文中。
import Control.Applicative ((<$>)
-- (<$>), fmap :: Functor f => (a -> b) -> f a -> f b
example1 :: (Int -> Int) -> Maybe Int -> Maybe Int
example1 f g = f <$> g -- f `fmap` (Just x) = Just (f x)
-- f `fmap` Nothing = Nothing
另一方面,当你在一个仿函数的上下文中有一个函数并且想要将它应用于另一个仿函数上下文中的某个值时,<*>
很有用,例如:
example2:: Maybe (Int -> Int) -> Maybe Int -> Maybe Int
example2 f g = f <*> g -- (Just f) <*> (Just x) = Just ( f x)
-- Nothing <*> (Just x ) = Nothing
-- (Just f) <*> Nothing = Nothing
-- Nothing <*> Nothing = Nothing
可以将其描绘为应用函数的运算符,同时考虑应用函数的上下文。
这些操作符将值和函数提升到执行操作的Functor的上下文中。