为什么不在 Applicative 上定义所有功能?

Why don't define all the functions over 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.

我认为在 Applicative 上定义所有函数对于许多情况(例如制作组合器)很有用。而applicative是对函数能力对应的适用性的抽象,这样做似乎也不错。

Applicative 上定义所有函数的预期问题是什么?

一个缺点是您现在不能再将它用于普通布尔值。所以,你必须写 pure True && pure False 而不是 True && False。如果你想得到结果,你必须使用 runIdentity :: Identity a -> a 或类似的东西。

一个更微妙的问题是你提出的函数不那么懒惰。通常,程序员期望 && 为 short-circuiting。所以写False && undefined应该还是returnFalse,但是写pure False && undefined函数就卡住了。你真的想将它实现为一个 monad:

(&&) :: Monad m => m Bool -> m Bool -> m Bool
x && y = do
  x' <- x
  if x
    then y
    else pure False

一个常见的替代方法是给它另一个名字,例如<&&>.