在SKI组合器中表达XOR

时间:2018-04-30 07:37:22

标签: haskell combinatory-logic

我正在尝试解决代码大战中的sure but can you SKI问题。它将在SKI组合器中表达lambda。来源位于https://repl.it/@delta4d/SKI

经过一些研究,特别是Combinatory Logic,我能够解决除xor之外的所有情况。

我首先将xor翻译成

xor x y = if y 
          then if x
               then false
               else true
          else x

xor = \x y -> y (x false true) x
-- false = K I
-- true = K

将lambda应用于SKI规则,我得到了

\x.\y.y (x false true) x
\x.S (\y.y (x false true)) (K x)
\x.S (S I (K (x false true))) (K x)
S (\x.S (S I (K (x false true)))) K
S (S (K S) (\x.S I (K (x false true)))) K
S (S (K S) (S (K (S I)) (\x.K (x false true)))) K
S (S (K S) (S (K (S I)) (S (K K) (\x.x false true)))) K
S (S (K S) (S (K (S I)) (S (K K) (S (\x.x false) (K true))))) K
S (S (K S) (S (K (S I)) (S (K K) (S (S I (K false)) (K true))))) K

我已在http://ski.aditsu.net检查了SKI演示文稿,它运行正常。

Haskell源代码编译,但出现运行时错误。

Codewars报告:

Couldn't match type `a' with `Bool' a'
  `a' is a rigid type variable bound by
      a type expected by the context: a -> a -> a at Kata.hs:66:9
Expected type: SKI
                 (Bool' a -> (Bool' a -> Bool' a -> Bool' a) -> a -> a -> a)
  Actual type: SKI (Bool' (Bool' a))
In the second argument of `xorF', namely `true'
In the second argument of `($)', namely `xorF true true'

我在prettyPrintSKI $ Ap (Ap xor' false) true的本地测试,并报告:

• Occurs check: cannot construct the infinite type: a20 ~ Bool' a20
  Expected type: SKI
                   (Bool' a20 -> (Bool' a20 -> Bool' a20 -> Bool' a20) -> Bool' a20)
    Actual type: SKI (Bool' (Bool' a20))
• In the second argument of ‘Ap’, namely ‘true’
  In the second argument of ‘($)’, namely ‘Ap (Ap xor' false) true’
  In the expression: prettyPrintSKI $ Ap (Ap xor' false) true

关于什么是无限类型?什么是刚性类型?

我在oror = \x y -> x true y做同样的事情,并且效果很好。

  1. https://www.codewars.com/kata/sure-but-can-you-ski-i
  2. https://en.wikipedia.org/wiki/Combinatory_logic
  3. http://ski.aditsu.net

1 个答案:

答案 0 :(得分:2)

问题来自于xλxy.y (x false true) x的双重使用。它被迫同时拥有两种类型。由于y使用xy必须返回类似a类型的内容。现在这意味着x false true也是a类型。因此a类型的内容必须为(b -> b -> a)(对于某些b)。但这是不可能的,因为这意味着a必须包含自己。

值得注意的是,您的解决方案是正确的。 SK,不是Haskell的类型系统。因此,为了解决这个问题,我们不需要使用x两次使用不同的类型。那么为什么不用λxy.y(x false true)(x true false)使它们成为相同的类型?