{-# LANGUAGE PolyKinds, StandaloneDeriving #-}
module Data.SOP.Sing
(
SList(..)
, SListI
, sList
, para_SList
, case_SList
, Shape(..)
, shape
, lengthSList
) where
import Data.Kind (Type)
import Data.Proxy (Proxy(..))
import Data.SOP.Constraint
data SList :: [k] -> Type where
SNil :: SList '[]
SCons :: SListI xs => SList (x ': xs)
deriving instance Show (SList (xs :: [k]))
deriving instance Eq (SList (xs :: [k]))
deriving instance Ord (SList (xs :: [k]))
para_SList ::
SListI xs
=> r '[]
-> (forall y ys . (SListI ys) => r ys -> r (y ': ys))
-> r xs
para_SList nil cons =
cpara_SList (Proxy :: Proxy Top) nil cons
{-# INLINE para_SList #-}
case_SList ::
SListI xs
=> r '[]
-> (forall y ys . (SListI ys) => r (y ': ys))
-> r xs
case_SList nil cons =
ccase_SList (Proxy :: Proxy Top) nil cons
{-# INLINE case_SList #-}
sList :: SListI xs => SList xs
sList = ccase_SList (Proxy :: Proxy Top) SNil SCons
data Shape :: [k] -> Type where
ShapeNil :: Shape '[]
ShapeCons :: SListI xs => Shape xs -> Shape (x ': xs)
deriving instance Show (Shape xs)
deriving instance Eq (Shape xs)
deriving instance Ord (Shape xs)
shape :: forall (xs :: [k]). SListI xs => Shape xs
shape = case sList :: SList xs of
SNil -> ShapeNil
SCons -> ShapeCons shape
lengthSList :: forall (xs :: [k]) proxy. SListI xs => proxy xs -> Int
lengthSList _ = lengthShape (shape :: Shape xs)
where
lengthShape :: forall xs'. Shape xs' -> Int
lengthShape ShapeNil = 0
lengthShape (ShapeCons s) = 1 + lengthShape s