lun*_*nuy 0 haskell applicative
internalAnd :: Bool -> Bool -> Bool
internalAnd True True = True
internalAnd _ _ = False
(&&) :: Applicative m => m Bool -> m Bool -> m Bool
(&&) = liftA2 internalAnd
-- Usage
greaterThan x = (x <)
lessThan x = (x >)
validateAge = greaterThan 0 && lessThan 120 -- It's really useful with combinators.
Run Code Online (Sandbox Code Playgroud)
Applicative我认为对于许多情况(例如创建组合器)定义所有函数很有用。而applicative是对适用性的抽象,对应于函数的能力,所以这样做似乎也不错。
定义所有函数的预期问题是什么Applicative?
一个缺点是您现在不能再将它用于普通布尔值。所以,你必须写pure True && pure False而不是True && False. 如果你想得到结果,你就必须使用runIdentity :: Identity a -> a或类似的东西。
一个更微妙的问题是您提出的函数不太懒惰。通常,程序员预计&&会发生短路。False所以如果你写它仍然应该返回False && undefined,但是如果你写你的函数将会卡住pure False && undefined。实际上你想将它实现为一个 monad:
(&&) :: Monad m => m Bool -> m Bool -> m Bool
x && y = do
x' <- x
if x
then y
else pure False
Run Code Online (Sandbox Code Playgroud)
一个常见的替代方法是给它另一个名称,例如<&&>。