简体   繁体   中英

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.

I think it is useful to define all functions over Applicative for many situation like making combinators. And applicative is abstraction of applicability that is corresponding to function's ability, so it seems not bad to do like this.

What is expected problems of defining all the functions over Applicative ?

One disadvantage is that you now cannot use it for normal booleans anymore. So, you'd have to write pure True && pure False instead of True && False . And if you want to get at the result you'd have to use runIdentity:: Identity a -> a or something like that.

A more subtle problem is that your proposed function is less lazy. Usually, programmers expect && to be short-circuiting. So it should still return False if you write False && undefined , but your function will get stuck if you write pure False && undefined . Really you'd want to implement it as a monad:

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

A common alternative is to give it another name, eg <&&> .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM