如果丢弃第一个或第二个参数,为什么需要这些函数(*>)或(< *)?

时间:2017-11-13 15:58:52

标签: haskell functional-programming applicative

The type signature of the function (*>)就是这样:

(*>) :: f a -> f b -> f b 
     

序列动作,丢弃第一个参数的值。

有人可以解释为什么这有用吗?如果第一个参数被丢弃,似乎反直觉。

请举例说明。感谢。

2 个答案:

答案 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 aEither 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"