用函子在haskell中写XOR

用函子在haskell中写XOR,haskell,functor,boolean-logic,applicative,Haskell,Functor,Boolean Logic,Applicative,我对haskell比较陌生,最近才了解了应用函子,我为xor编写了这段代码,只使用函子和布尔函数。我想知道你们能不能想出一个更短的关于函子的解决方案(我肯定存在) xor :: Bool->Bool->Bool xor=(<$>) (not<$>) ((<*>).((((not<$>)<$>(&&))<$>)<$>((not<$>)<$>(&&)

我对haskell比较陌生,最近才了解了应用函子,我为xor编写了这段代码,只使用函子和布尔函数。我想知道你们能不能想出一个更短的关于函子的解决方案(我肯定存在)

xor :: Bool->Bool->Bool
xor=(<$>) (not<$>) ((<*>).((((not<$>)<$>(&&))<$>)<$>((not<$>)<$>(&&)))<*>(||))
异或::Bool->Bool->Bool xor=()(非)(())(((非)(&&&))((非)(&&&))(| |) 我知道这可能不是很好的做法;这对我来说更像是脑筋急转弯


PS我希望这是允许的

好吧,这真的是毫无意义和愚蠢的,但是嘿嘿

首先,我定义了
xor
不是
|

xor a b = (a || b) && (not a || not b)
那么如果我使用
(&&&)ab=not(nota | | not b)

xor a b = not ( not (not a || not b) || not (a || b) )
这已经足够低级了。然后,我运行了它以得到以下结果:

xor = (not .) . ap (ap . (((||) . not) .) . (. not) . (||) . not) ((not .) . (||))
现在,
Control中的
ap
。Monad
是与
()
等价的单子,
()
是函数Monad中的
()
,因此我们可以替换一些东西:

xor = (not<$>)<$>(<*>)((<*>)<$>(((||)<$>not)<$>)<$>(<$>not)<$>(||)<$> not)((not<$>)<$>(||))
xor=(not)((((| |)not))(not)(| |)not)((not)(| |)

瞧,这真是一个愚蠢得可笑的函数,没有什么特别的功能!击倒自己。

这里有一个解决方案,你可以用手写(和阅读,需要一些指导!)。正如@AJFarmar所指出的,我们可以写作

xor a b = (a || b) && (not a || not b)
我也将使用他建议的重写,即
a&&b=not(nota | | not b)
,尽管他做了相反的操作:

xor a b = (a || b) && not (a && b)
对于其他定义,您可以遵循以下过程,但这是一个特别简短的开始定义

现在我们可以挑选出块
a | | b
a&b
,而不是在一个有
a::Bool
b::Bool
的环境中把它们转换成一种形式,在这种形式中,我们把它们看作是
Bool
类型的值,有两个
Applicative
“context”包装纸。因此,
(| |)::f(g Bool)
(&&&)::f(g Bool)
,其中
f
g
是特定的
应用程序实例
(>)Bool
。所以我们处于部分翻译状态

xor = (||) && not (&&)
现在唯一的问题是中缀
&&
期望纯
Bool
值,但被双重包装
Bool
s。因此,我们将使用双
liftA*
应用程序提升它们。因此:

xor = liftA2 (liftA2 (&&)) (||) (liftA (liftA not) (&&))
还有其他的拼写方法。我更喜欢
()
这个名字,而不是
liftA
。此外,可以将双重包装的
Applicative
s看作是具有更复杂包装的单独包装的东西,因此:

xor = getCompose (liftA2 (&&) (Compose (||)) (not <$> Compose (&&)))
xor=getCompose(liftA2(&&&)(Compose(&))(notcompose(&&))

为什么要把它弄得更复杂?

这是属于它的吗?我不确定,因为它是特定于语言的,我认为codegolf更像是一种有趣的挑战类型,而在这里我更努力地学习如何使用functor编写较短的代码。你可以使用
(| |)和
xor a b=not$not(not a | | not b)| not(a | | b)
不,不,不,不,不,不,不,不,不,不,不,不,不,不,不,不,不,不,不,不,不,不,不,不,不,不,不,不,不,不,这对你来说够短吗
…哈哈,这是一个很好的观点,但为了论证起见,让我们使用函子路线。很好!我找不到手工编写的方法,但这很好!呃,这应该看起来像Perl代码,或者更像脑力操吗?@leftaroundabout Aw耶!
xor = (/=)