在任何编程语言中,== 是否对逻辑 OR 具有分配性? (我们可以把 (a==b || a==c) 写成 a==(b||c) 吗?
is == distributive over logical OR in any programming language ? ( can we write (a==b || a==c) as a==(b||c))
是否有任何编程语言可以将 (a==b || a==c)
写成 a==(b||c)
?
换句话说,在任何编程语言中,==
是否对逻辑 OR
具有分配性? (我们可以把(a==b || a==c)
写成a==(b||c)
)吗?
多种语言中都有类似的结构。 IN
in SQL,in
in python,等等,大多数评估列表或数组。我知道的最接近的是 Haskell 的 or
类型 [Bool] -> Bool.
正如 Anton Gogolev 所说,很难为 b || 找到合适的类型c,但也不是完全不可能。
您可能必须定义高阶函数 (|||) :: forall a . a -> a -> ((a -> Bool) -> Bool)
作为 a (|||) b = \f -> (f x) || (f y)
实现(这里 \
表示 lambda 表达式)。
现在您可以使用这个 (b ||| c) (== 42)
。
或者你可以这样做:
(|||) :: forall a b . a -> a -> (a -> b -> Bool) -> b -> Bool
(|||) x y f b = (f x b) || (f y b)
现在你可以做到 ( a ||| b ) (==) 42
当然,上述 none 可以在缺少高阶函数的语言中使用。此外,相等 (==) 必须是函数而不是语言构造。 (但是,您可以使用 Promises 获得类似的效果)。
也许以上几行暗示了为什么这种方法在野外不常用。 :) a in [b,c]
使用起来简单多了。
编辑:(为了好玩)
您可以使用包装器类型来实现目标(Haskell):
data F a = (Eq a) => Fn (a -> (a->a->Bool) -> Bool) | N a
(===) :: Eq a => F a -> F a -> Bool
(Fn f) === (N n) = f n (==)
(N n) === (Fn f) = f n (==)
(N a) === (N b) = a == b
(Fn a) === (Fn b) = error "not implemented"
(|||) :: Eq a => F a -> F a -> F a
N a ||| N b = Fn $ \c f -> (a `f` c) || (b `f` c)
Fn a ||| N b = Fn $ \c f -> a c f || ( b `f` c )
N a ||| Fn b = Fn $ \c f -> b c f || ( a `f` c )
Fn a ||| Fn b = Fn $ \c f -> (a c f) || (b c f)
现在我们的新 (===) 分配给 (|||)。已经做出一些努力来保持关联和交换属性。现在我们可以拥有以下所有内容:
N 1 === N 2
N 3 === ( N 3 ||| N 8 ||| N 5 )
( N 3 ||| N 8 ||| N 5 ) === N 0
N "bob" === ( N "pete" ||| N "cecil" ||| N "max")
N a === ( N 9 ||| N b ||| N c)
一切都会顺利进行。我们可以用基本类型替换标准运算符和类型 N,并写成 3 == (3 || 8 || 5)。你要的也不是不可能。
该构造是通用的,您可以使用 (>=) :: F a -> F a -> Bool
之类的东西轻松扩展它,现在您可以使用 ( 100 || 3 || a || b ) >= c
。 (请注意没有使用列表或数组。)
是否有任何编程语言可以将 (a==b || a==c)
写成 a==(b||c)
?
换句话说,在任何编程语言中,==
是否对逻辑 OR
具有分配性? (我们可以把(a==b || a==c)
写成a==(b||c)
)吗?
多种语言中都有类似的结构。 IN
in SQL,in
in python,等等,大多数评估列表或数组。我知道的最接近的是 Haskell 的 or
类型 [Bool] -> Bool.
正如 Anton Gogolev 所说,很难为 b || 找到合适的类型c,但也不是完全不可能。
您可能必须定义高阶函数 (|||) :: forall a . a -> a -> ((a -> Bool) -> Bool)
作为 a (|||) b = \f -> (f x) || (f y)
实现(这里 \
表示 lambda 表达式)。
现在您可以使用这个 (b ||| c) (== 42)
。
或者你可以这样做:
(|||) :: forall a b . a -> a -> (a -> b -> Bool) -> b -> Bool
(|||) x y f b = (f x b) || (f y b)
现在你可以做到 ( a ||| b ) (==) 42
当然,上述 none 可以在缺少高阶函数的语言中使用。此外,相等 (==) 必须是函数而不是语言构造。 (但是,您可以使用 Promises 获得类似的效果)。
也许以上几行暗示了为什么这种方法在野外不常用。 :) a in [b,c]
使用起来简单多了。
编辑:(为了好玩)
您可以使用包装器类型来实现目标(Haskell):
data F a = (Eq a) => Fn (a -> (a->a->Bool) -> Bool) | N a
(===) :: Eq a => F a -> F a -> Bool
(Fn f) === (N n) = f n (==)
(N n) === (Fn f) = f n (==)
(N a) === (N b) = a == b
(Fn a) === (Fn b) = error "not implemented"
(|||) :: Eq a => F a -> F a -> F a
N a ||| N b = Fn $ \c f -> (a `f` c) || (b `f` c)
Fn a ||| N b = Fn $ \c f -> a c f || ( b `f` c )
N a ||| Fn b = Fn $ \c f -> b c f || ( a `f` c )
Fn a ||| Fn b = Fn $ \c f -> (a c f) || (b c f)
现在我们的新 (===) 分配给 (|||)。已经做出一些努力来保持关联和交换属性。现在我们可以拥有以下所有内容:
N 1 === N 2
N 3 === ( N 3 ||| N 8 ||| N 5 )
( N 3 ||| N 8 ||| N 5 ) === N 0
N "bob" === ( N "pete" ||| N "cecil" ||| N "max")
N a === ( N 9 ||| N b ||| N c)
一切都会顺利进行。我们可以用基本类型替换标准运算符和类型 N,并写成 3 == (3 || 8 || 5)。你要的也不是不可能。
该构造是通用的,您可以使用 (>=) :: F a -> F a -> Bool
之类的东西轻松扩展它,现在您可以使用 ( 100 || 3 || a || b ) >= c
。 (请注意没有使用列表或数组。)