为什么不在 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
一个常见的替代方法是给它另一个名字,例如<&&>
.
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
一个常见的替代方法是给它另一个名字,例如<&&>
.