{-# LANGUAGE NoMonomorphismRestriction #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE KindSignatures #-} {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE OverlappingInstances #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE PolyKinds #-} module Data.RTuple where import Prelude hiding (head, tail, map) import Data.Typeable import GHC.TypeLits import Unsafe.Coerce (unsafeCoerce) import Type.Bool import Control.Lens import Control.Lens.Wrapped ---------------------------------------------------------------------------------- -- RTuple ---------------------------------------------------------------------------------- data RTuple a = RTuple { fromRTuple :: a } deriving (Eq, Ord) data TList (t :: *) a = TList { fromTList :: a } deriving (Eq, Ord) --type family --type family RTupData rt where RTupData (RTuple a) = a --infixr 0 // --(//) = (,) -- === Wrapper === instance Wrapped (RTuple a) where type Unwrapped (RTuple a) = a _Wrapped' = iso fromRTuple RTuple instance Wrapped (TList t a) where type Unwrapped (TList t a) = a _Wrapped' = iso fromTList TList -- === Show === class ShowRtup r where showRtup :: String -> r -> String instance ShowRtup () where showRtup _ _ = "" instance Show a => ShowRtup (a,()) where showRtup _ (a,()) = show a instance (Show a, ShowRtup as) => ShowRtup (a,as) where showRtup sep (a,as) = show a ++ sep ++ showRtup sep as instance ShowRtup a => Show (RTuple a) where show (RTuple a) = "RTuple (" ++ showRtup ", " a ++ ")" -- === Head === type family HeadOf a type instance HeadOf (RTuple (r,rs)) = r type instance HeadOf (TList a l) = a class Head a where head :: Lens' a (HeadOf a) instance Head (RTuple (r,rs)) where head = lens (fst . view _Wrapped') (\(RTuple (_,rs)) r -> RTuple (r,rs)) instance (a ~ r) => Head (TList a (r,rs)) where head = lens (fst . view _Wrapped') (\(TList (_,rs)) r -> TList (r,rs)) -- === Tail === type family TailOf a type instance TailOf (RTuple (r,rs)) = RTuple rs type instance TailOf (TList a (r,rs)) = TList a rs class Tail a where tail :: Lens' a (TailOf a) instance Tail (RTuple (r,rs)) where tail = lens (\(RTuple (r,rs)) -> RTuple rs) (\(RTuple (r,_)) (RTuple rs) -> RTuple (r,rs)) instance Tail (TList a (r,rs)) where tail = lens (\(TList (r,rs)) -> TList rs) (\(TList (r,_)) (TList rs) -> TList (r,rs)) -- === UncurryTuple === -- |converts function taking a tuple list as argument into standard haskell one -- eg. `(a,(b,(c,()))) -> out` into `a -> b -> c -> out` class UncurryTuple f out | f -> out where uncurryTuple :: f -> out instance UncurryTuple (RTuple () -> a) a where uncurryTuple f = f $ RTuple () instance UncurryTuple (RTuple xs -> f) fout => UncurryTuple (RTuple (x,xs) -> f) (x -> fout) where uncurryTuple f = (\x -> uncurryTuple $ f . RTuple . (x,) . fromRTuple) -- === ToRTup === type family AsRTuple (a :: k) type instance AsRTuple ('[] :: [*]) = RTuple () type instance AsRTuple ((l ': ls) :: [*]) = RTuple (l, Unwrapped (AsRTuple ls)) type family AsTListData t (a :: k) type AsTList t lst = TList t (AsTListData t lst) type instance AsTListData t ('[] :: [*]) = () type instance AsTListData t ((l ': ls) :: [*]) = (t, Unwrapped (AsTList t ls)) -- === ToTuple === -- TODO [refactor to a tuple package] type family AsTuple a type instance AsTuple (RTuple ()) = () type instance AsTuple (RTuple (t1,())) = t1 class ToTuple a lst | a -> lst where toTuple :: a -> lst instance ToTuple (RTuple ()) () where toTuple _ = () instance ToTuple (RTuple (t1,())) t1 where toTuple (RTuple (t1,())) = t1 instance ToTuple (RTuple (t1,(t2,()))) (t1,t2) where toTuple (RTuple (t1,(t2,()))) = (t1,t2) instance ToTuple (RTuple (t1,(t2,(t3,())))) (t1,t2,t3) where toTuple (RTuple (t1,(t2,(t3,())))) = (t1,t2,t3) instance ToTuple (RTuple (t1,(t2,(t3,(t4,()))))) (t1,t2,t3,t4) where toTuple (RTuple (t1,(t2,(t3,(t4,()))))) = (t1,t2,t3,t4) instance ToTuple (RTuple (t1,(t2,(t3,(t4,(t5,())))))) (t1,t2,t3,t4,t5) where toTuple (RTuple (t1,(t2,(t3,(t4,(t5,())))))) = (t1,t2,t3,t4,t5) instance ToTuple (RTuple (t1,(t2,(t3,(t4,(t5,(t6,()))))))) (t1,t2,t3,t4,t5,t6) where toTuple (RTuple (t1,(t2,(t3,(t4,(t5,(t6,()))))))) = (t1,t2,t3,t4,t5,t6) instance ToTuple (RTuple (t1,(t2,(t3,(t4,(t5,(t6,(t7,())))))))) (t1,t2,t3,t4,t5,t6,t7) where toTuple (RTuple (t1,(t2,(t3,(t4,(t5,(t6,(t7,())))))))) = (t1,t2,t3,t4,t5,t6,t7) instance ToTuple (RTuple (t1,(t2,(t3,(t4,(t5,(t6,(t7,(t8,()))))))))) (t1,t2,t3,t4,t5,t6,t7,t8) where toTuple (RTuple (t1,(t2,(t3,(t4,(t5,(t6,(t7,(t8,()))))))))) = (t1,t2,t3,t4,t5,t6,t7,t8) instance ToTuple (RTuple (t1,(t2,(t3,(t4,(t5,(t6,(t7,(t8,(t9,())))))))))) (t1,t2,t3,t4,t5,t6,t7,t8,t9) where toTuple (RTuple (t1,(t2,(t3,(t4,(t5,(t6,(t7,(t8,(t9,())))))))))) = (t1,t2,t3,t4,t5,t6,t7,t8,t9) instance ToTuple (RTuple (t1,(t2,(t3,(t4,(t5,(t6,(t7,(t8,(t9,(t10,()))))))))))) (t1,t2,t3,t4,t5,t6,t7,t8,t9,t10) where toTuple (RTuple (t1,(t2,(t3,(t4,(t5,(t6,(t7,(t8,(t9,(t10,()))))))))))) = (t1,t2,t3,t4,t5,t6,t7,t8,t9,t10) instance ToTuple (RTuple (t1,(t2,(t3,(t4,(t5,(t6,(t7,(t8,(t9,(t10,(t11,())))))))))))) (t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11) where toTuple (RTuple (t1,(t2,(t3,(t4,(t5,(t6,(t7,(t8,(t9,(t10,(t11,())))))))))))) = (t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11) instance ToTuple (RTuple (t1,(t2,(t3,(t4,(t5,(t6,(t7,(t8,(t9,(t10,(t11,(t12,()))))))))))))) (t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12) where toTuple (RTuple (t1,(t2,(t3,(t4,(t5,(t6,(t7,(t8,(t9,(t10,(t11,(t12,()))))))))))))) = (t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12) -- === Elem indexing === type family ElTypeAt (idx :: Nat) a class ElAt idx a where elAt :: Proxy idx -> Lens' a (ElTypeAt idx a) class ElAt' idx t where elAt' :: Proxy idx -> Lens' (TList t lst) t -- type instance ElTypeAt n (RTuple (r,rs)) = If (n :== 0) r (ElTypeAt (n - 1) (RTuple rs)) --type instance ElTypeAt n (TList t (r,rs)) = If (n :== 0) t (ElTypeAt (n - 1) (TList t rs)) type instance ElTypeAt n (TList t lst) = t instance {-# OVERLAPPABLE #-} ( ElAt (n - 1) (RTuple rs) , ElTypeAt n (RTuple (r,rs)) ~ ElTypeAt (n-1) (RTuple rs) ) => ElAt n (RTuple (r,rs)) where elAt _ = tail . elAt (Proxy :: Proxy (n-1)) instance {-# OVERLAPPABLE #-} ElAt 0 (RTuple (r,rs)) where elAt _ = head instance {-# OVERLAPPABLE #-} ( ElAt (n - 1) (TList t rs) , ElTypeAt n (TList t (r,rs)) ~ ElTypeAt (n-1) (TList t rs) ) => ElAt n (TList t (r,rs)) where elAt _ = tail . elAt (Proxy :: Proxy (n-1)) instance {-# OVERLAPPABLE #-} (t ~ r) => ElAt 0 (TList t (r,rs)) where elAt _ = head -- === RTup builder === --rtup = --class RTupBuilder b where -- rtup :: --elAt0 :: ElTypeAt 0 a => a -> ElAt 0 a --elAt0 = ElTypeAt (Proxy :: Proxy 0) --elAt1 :: ElTypeAt 1 a => a -> ElAt 1 a --elAt1 = ElTypeAt (Proxy :: Proxy 1) --elAt2 :: ElTypeAt 2 a => a -> ElAt 2 a --elAt2 = ElTypeAt (Proxy :: Proxy 2) --elAt3 :: ElTypeAt 3 a => a -> ElAt 3 a --elAt3 = ElTypeAt (Proxy :: Proxy 3) --elAt4 :: ElTypeAt 4 a => a -> ElAt 4 a --elAt4 = ElTypeAt (Proxy :: Proxy 4) --elAt5 :: ElTypeAt 5 a => a -> ElAt 5 a --elAt5 = ElTypeAt (Proxy :: Proxy 5) --elAt6 :: ElTypeAt 6 a => a -> ElAt 6 a --elAt6 = ElTypeAt (Proxy :: Proxy 6) --elAt7 :: ElTypeAt 7 a => a -> ElAt 7 a --elAt7 = ElTypeAt (Proxy :: Proxy 7) --elAt8 :: ElTypeAt 8 a => a -> ElAt 8 a --elAt8 = ElTypeAt (Proxy :: Proxy 8) --elAt9 :: ElTypeAt 9 a => a -> ElAt 9 a --elAt9 = ElTypeAt (Proxy :: Proxy 9)