如果函数(*>;)或(<;*)放弃了第一个或第二个参数,为什么需要它们



函数(*>)的类型签名如下:

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

顺序操作,放弃第一个参数的值。

有人能解释一下为什么这很有用吗?如果第一个论点被丢弃,似乎有违直觉。

请举例说明。谢谢

让我们假设这里的应用函子已经是一个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."

所以你可以看到,当"结果"被丢弃时,结果只是一元作用或应用函子作用的一部分。

丢弃参数的"shape"仍在使用。把Applicative f => f a的值想象成具有a类型的一些值,这些值被应用函子f以某种形状排列。运算符<*> :: Applicative f => f (a -> b) -> f a -> f b将其前两个自变量的形状组合起来,得出第三个形状。pure x总是有一个简单的"唯一性"形状,不会改变另一个形状。

这两个运算符的定义等价于:

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进行评估时,其结果将具有ab相结合的形状。

CCD_ 19和CCD_。它们没那么有趣。

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"

最新更新