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