Created
November 29, 2014 10:02
-
-
Save gergoerdi/727f028e4c1ed158ac9a to your computer and use it in GitHub Desktop.
This file contains hidden or 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
{- | |
- Instant Insanity using Type Families. | |
- | |
- See: The Monad Read, Issue #8 - http://www.haskell.org/wikiupload/d/dd/TMR-Issue8.pdf | |
-} | |
{-# OPTIONS_GHC -ftype-function-depth=400 #-} | |
{-# LANGUAGE MultiParamTypeClasses #-} | |
{-# LANGUAGE TypeFamilies #-} | |
{-# LANGUAGE UndecidableInstances #-} | |
import Prelude hiding (all, flip, map, filter ) | |
data Proxy a = Proxy | |
main = print (Proxy :: Proxy (Solutions Cubes)) | |
data R -- Red | |
data G -- Green | |
data B -- Blue | |
data W -- White | |
data Cube u f r b l d | |
data True | |
data False | |
type family And b1 b2 :: * | |
type instance And True True = True | |
type instance And True False = False | |
type instance And False False = False | |
type instance And False True = False | |
type family NE x y :: * | |
type instance NE R R = False | |
type instance NE R G = True | |
type instance NE R B = True | |
type instance NE R W = True | |
type instance NE G R = True | |
type instance NE G G = False | |
type instance NE G B = True | |
type instance NE G W = True | |
type instance NE B R = True | |
type instance NE B G = True | |
type instance NE B B = False | |
type instance NE B W = True | |
type instance NE W R = True | |
type instance NE W G = True | |
type instance NE W B = True | |
type instance NE W W = False | |
type family EQ x y :: * | |
type instance EQ R R = True | |
type instance EQ R G = False | |
type instance EQ R B = False | |
type instance EQ R W = False | |
type instance EQ G R = False | |
type instance EQ G G = True | |
type instance EQ G B = False | |
type instance EQ G W = False | |
type instance EQ B R = False | |
type instance EQ B G = False | |
type instance EQ B B = True | |
type instance EQ B W = False | |
type instance EQ W R = False | |
type instance EQ W G = False | |
type instance EQ W B = False | |
type instance EQ W W = True | |
data Nil = Nil | |
data Cons x xs = Cons x xs | |
type family All l :: * | |
type instance All Nil = True | |
type instance All (Cons False xs) = False | |
type instance All (Cons True xs) = All xs | |
type family ListConcat xs ys :: * | |
type instance ListConcat Nil ys = ys | |
type instance ListConcat (Cons x xs) ys = Cons x (ListConcat xs ys) | |
type family AppendIf b a as :: * | |
type instance AppendIf False a as = as | |
type instance AppendIf True a as = Cons a as | |
data Rotate | |
data Twist | |
data Flip | |
type family Apply f a :: * | |
type instance Apply Rotate (Cube u f r b l d) = (Cube u r b l f d) | |
type instance Apply Twist (Cube u f r b l d) = (Cube f r u l d b) | |
type instance Apply Flip (Cube u f r b l d) = (Cube d l b r f u) | |
-- orientations c = [ z | x <- [ c, flip c ], y <- [ x, twist x, twist (twist x) ], z <- [y, rot y, rot(rot y), rot(rot(rot(y))) ] ] | |
type family Map f as :: * | |
type instance Map f Nil = Nil | |
type instance Map f (Cons a as) = Cons (Apply f a) (Map f as) | |
type family MapAppend f as :: * | |
type instance MapAppend f xs = ListConcat xs (Map f xs) | |
type family MapAppend2 f as :: * | |
type instance MapAppend2 f xs = ListConcat xs (MapAppend f (Map f xs)) | |
type family MapAppend3 f as :: * | |
type instance MapAppend3 f xs = ListConcat xs (MapAppend2 f (Map f xs)) | |
type family Iterate2 f as :: * | |
type instance Iterate2 f Nil = Nil | |
type instance Iterate2 f (Cons a as) = ListConcat (Cons (Apply f a) (Cons a Nil)) (Iterate2 f as) | |
type family Iterate3 f as :: * | |
type instance Iterate3 f (Cons a as) = | |
ListConcat (Cons a | |
(Cons (Apply f a) | |
(Cons (Apply f (Apply f a)) | |
Nil))) | |
(Iterate3 f as) | |
type family Iterate4 f as :: * | |
type instance Iterate4 f Nil = Nil | |
type instance Iterate4 f (Cons a as) = | |
ListConcat (Cons a | |
(Cons (Apply f a) | |
(Cons (Apply f (Apply f a)) | |
(Cons (Apply f (Apply f (Apply f a))) | |
Nil)))) | |
(Iterate4 f as) | |
type family Orientations c :: * | |
-- type instance Orientations c = Iterate4 Rotate (Iterate3 Twist (Iterate2 Flip (Cons c Nil))) | |
type instance Orientations c = MapAppend3 Rotate (MapAppend2 Twist (MapAppend Flip (Cons c Nil))) | |
type Cube1 = Cube B G W G B R | |
type Cube2 = Cube W G B W R R | |
type Cube3 = Cube G W R B R R | |
type Cube4 = Cube B R G G W W | |
type Cubes = Cons Cube1 (Cons Cube2 (Cons Cube3 (Cons Cube4 Nil))) | |
type family Compatible c d :: * | |
type instance Compatible (Cube u1 f1 r1 b1 l1 d1) (Cube u2 f2 r2 b2 l2 d2) = | |
All (Cons (NE f1 f2) (Cons (NE r1 r2) (Cons (NE b1 b2) (Cons (NE l1 l2) Nil)))) | |
type family Allowed c cs :: * | |
type instance Allowed c Nil = True | |
type instance Allowed c (Cons s ss) = And (Compatible c s) (Allowed c ss) | |
type family MatchingOrientations as sol :: * | |
type instance MatchingOrientations Nil sol = Nil | |
type instance MatchingOrientations (Cons o os) sol = AppendIf (Allowed o sol) (Cons o sol) (MatchingOrientations os sol) | |
type family AllowedCombinations os sols :: * | |
type instance AllowedCombinations os Nil = Nil | |
type instance AllowedCombinations os (Cons sol sols) = ListConcat (MatchingOrientations os sol) (AllowedCombinations os sols) | |
type family Solutions c :: * | |
type instance Solutions Nil = Cons Nil Nil | |
type instance Solutions (Cons c cs) = AllowedCombinations (Orientations c) (Solutions cs) | |
{- | |
- solutions [] = [ [] ] | |
- solutions (c:cs) = [ (o:sol) | sol <- solutions cs, o <- orientations c, allowed o sol ] | |
- | |
-} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment