I am trying to solve sure but can you SKI on codewars. It is about to express lambda in SKI combinators. Source is at https://repl.it/@delta4d/SKI.
After some researching, especially the Combinatory Logic, I am able to solve all the cases except xor
.
I first translates xor into
xor x y = if y
then if x
then false
else true
else x
which is
xor = \x y -> y (x false true) x
-- false = K I
-- true = K
applying lambda to SKI rules, I got
\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
I have checked the SKI presentation on http://ski.aditsu.net, it works fine.
Haskell sources compiles, but got runtime error.
Codewars reports:
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'
I have test on local with prettyPrintSKI $ Ap (Ap xor' false) true
, and it reports:
• 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
What is the infinite type about? what is the rigid type?
I am doing the same thing on or
as or = \x y -> x true y
, and it works just fine.
The problem comes from the double use of x
in λxy.y (x false true) x
. It's forced to have two types simultaneously. Since y
uses x
, y
must return something of let's say type a
. Now this means that x false true
is also of type a
. So something of type a
must be (b -> b -> a)
(for some b
). But that's impossible, since that means a
must contain itself.
It's worth noting that your solution is correct wrt. SK, just not Haskell's type system. So to fix we need to not use x
twice with different types. So why not make them the same type with λxy.y(x false true)(x true false)
?