Created
June 5, 2022 13:39
-
-
Save mjgpy3/d0c9b4b7280b0b3d37231e6b6b2e9724 to your computer and use it in GitHub Desktop.
SKI Combinators
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Lib | |
( Ski(..) | |
, eval | |
, someFunc | |
) where | |
import Test.QuickCheck | |
data Ski | |
= I | |
| K | |
| S | |
| App Ski Ski | |
deriving (Show, Eq) | |
instance Arbitrary Ski where | |
arbitrary = do | |
f <- arbitrary | |
x <- arbitrary | |
elements [S, K, I, App f x] | |
eval :: Ski -> Ski | |
eval (App (App K x) y) = eval x | |
eval (App (App (App S x) y) z) = eval $ App (App x z) (App y z) | |
eval (App I x) = eval x | |
eval (App K x) = App K $ eval x | |
eval (App f x) = eval (App (eval f) x) | |
eval x = x | |
someFunc :: IO () | |
someFunc = putStrLn "someFunc" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Lib | |
import Test.Hspec | |
import Test.QuickCheck | |
newtype ExprWithOnlyIAndApp = ExprWithOnlyIAndApp Ski | |
deriving Show | |
instance Arbitrary ExprWithOnlyIAndApp where | |
arbitrary = do | |
ExprWithOnlyIAndApp f <- arbitrary | |
ExprWithOnlyIAndApp x <- arbitrary | |
ExprWithOnlyIAndApp <$> elements [I, App f x] | |
main :: IO () | |
main = hspec $ do | |
describe "eval" $ do | |
it "I is irreducible" $ do | |
eval I `shouldBe` I | |
it "(I I) reduces to I" $ do | |
eval (App I I) `shouldBe` I | |
it "(I (I I)) reduces to I" $ do | |
eval (App I (App I I)) `shouldBe` I | |
it "((I I) I) reduces to I" $ do | |
eval (App (App I I) I) `shouldBe` I | |
it "arbitrarily nested applications of I only reduce to I" $ | |
property $ \(ExprWithOnlyIAndApp ski) -> eval ski == I | |
it "K is irreducible" $ do | |
eval K `shouldBe` K | |
it "(K I) is irreducible" $ do | |
eval (App K I) `shouldBe` App K I | |
it "(K K) is irreducible" $ do | |
eval (App K K) `shouldBe` App K K | |
it "in (K x), we can't get rid of K but x should be reduced" $ | |
property $ \(ExprWithOnlyIAndApp ski) -> eval (App K ski) == App K I | |
it "((K I) K) reduces to I" $ do | |
eval (App (App K I) K) `shouldBe` I | |
it "((K K) I) reduces to I" $ do | |
eval (App (App K K) I) `shouldBe` K | |
it "K K I S K reduces to S" $ do | |
eval (App (App (App (App K K) I) S) K) `shouldBe` S | |
it "K argument reduces" $ | |
property $ \(ExprWithOnlyIAndApp ski) -> eval (App (App K ski) K) == I | |
it "S is irreducible" $ do | |
eval S `shouldBe` S | |
it "S I I I reduces to I" $ do | |
eval (App (App (App S I) I) I) `shouldBe` I | |
it "S K K I reduces to I" $ do | |
eval (App (App (App S K) K) I) `shouldBe` I | |
context "wikipedia examples" $ do | |
it "SKI(KIS) reduces to I" $ do | |
eval (App (App (App S K) I) (App (App K I) S)) `shouldBe` I | |
it "KS(I(SKSI)) reduces to S" $ do | |
eval (App (App K S) (App I (App (App (App S K ) S ) I )) ) `shouldBe` S | |
it "SKIK reduces to K" $ do | |
eval (App (App (App S K) I) K) `shouldBe` K |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment