The type signature of the function (*>)
就是这样:
(*>) :: f a -> f b -> f b
序列动作,丢弃第一个参数的值。
有人可以解释为什么这有用吗?如果第一个参数被丢弃,似乎反直觉。
请举例说明。感谢。
答案 0 :(得分:8)
让我们假设我们的应用函子已经是monad。我们可以像这样实施*>
和<*
:
x *> y = do
x
y
x <* y = do
result <- x
y
return result
因此,您可以使用<*
和*>
来编写简单的内容,例如:
askForNumber :: IO Int
askForNumber = putStr "Please enter a number: " *> readLn <* putStrLn "Thank you."
所以你可以看到,当“结果”被丢弃时,结果只是monadic动作或应用函子动作的一部分。
答案 1 :(得分:2)
仍然使用丢弃的参数的“形状”。将Applicative f => f a
值视为具有类型a
的某些值,这些值以某种形状排列,由应用函子f实现。运算符<*> :: Applicative f => f (a -> b) -> f a -> f b
将前两个参数的形状组合在一起,形成第三个形状。 pure x
总是有一个简单的'idenitity'形状,不会改变另一个形状。
有问题的两个运营商的定义相当于:
a <* b = pure (\x y -> x) <*> a <*> b
a *> b = pure (\x y -> y) <*> a <*> b
pure
表达式具有身份形态,可以从第一个适用法律pure id <*> v = v
推断出来。因此,在评估pure (\x y -> ...) <*> a
时,其结果与a
具有相同的形状。它等同于fmap (\...) a
,其结果也与a
具有相同的形状。
然后,当评估(pure (\x y -> ...) <*> a) <*> b
时,其结果的形状为a
并结合b
。
Maybe a
和Either a b
只能有两种形状值。他们并不那么有趣。
Prelude> :set +t
Prelude> Just 'x' <* Just (1::Int)
Just 'x'
it :: Maybe Char
Prelude> Just 'x' <* (Nothing :: Maybe Int)
Nothing
it :: Maybe Char
Prelude> (Nothing :: Maybe Char) <* Just (1::Int)
Nothing
it :: Maybe Char
Prelude> (Nothing :: Maybe Char) <* (Nothing :: Maybe Char)
Nothing
it :: Maybe Char
对于列表,形状组合易于可视化。
Prelude> "ab" *> "123"
"123123"
Prelude> "ab" <* "123"
"aaabbb"