符号<$>
和<*>
代表什么意思?
此外,我了解到一些关于<$
和$>
的信息。
符号<$>
和<*>
代表什么意思?
此外,我了解到一些关于<$
和$>
的信息。
这些运算符在 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
Applicative
类型类位于 Functor
和 Monad
之间。class Functor where ...
class Functor f => Applicative f where ...
class Applicative m => Monad m where ...
Applicative
和Monad
之间的关系)
Applicative
是遵循特定规则的结构。 它比functor更强大,但比monad更弱。 具体而言,functor只能将单参数函数应用于结构中的值,返回一个包含新值但不包含新形状的新结构。 典型的例子是fmap(+1)[1,2,3] == [2,3,4]
,输入列表的长度总是与输出列表相同。 在applicatives中,您可以跨多个结构应用多参数纯函数:
> (+) <$> [1, 2, 3] <*> [10, 20]
[11, 21, 12, 22, 13, 23]
输出列表的长度(即其“形状”)取决于输入列表的长度。 但需要注意的是,输出列表的长度不取决于列表内部的值。 这正是单子为该层次结构增加的强大功能:
> print $ do a <- [1, 2, 3]; b <- replicate a 10; return (a + b)
[11, 12, 12, 13, 13, 13]
在这里,我们将两个结构体组合在一起,其中一个结构体的“形状”取决于另一个结构体中的值。仅使用应用程序无法实现此操作,这也是为什么单子在Haskell中如此普遍的原因。然而,由于每个Monad
都是一个Applicative
,而每个Applicative
都是一个Functor
,因此在使用Monad
时仍然可以访问所有这些工具。
[1, 2, 3]
吗? - Sebastian Redl1
而不是a
,感谢您指出。 - bheklilr<$>
而不是fmap
,所以预计会经常看到它。 - bheklilr(+) <$> [1,2,3]
实际上是[(1+), (2+), (3+)]
。 - mb14<$>
是fmap的同义词,<$>
是中缀运算符。它通常用于应用函子的上下文中。< /p >
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
另一方面,<*>
在将函数应用于另一个 functor 上下文中的某个值时非常有用,例如:
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的上下文中,其中执行操作。