Skip to content

Instantly share code, notes, and snippets.

@drchaos
Created November 7, 2019 10:43
Show Gist options
  • Save drchaos/6823545972cf18ca2fd6b3500b2ce1bd to your computer and use it in GitHub Desktop.
Save drchaos/6823545972cf18ca2fd6b3500b2ce1bd to your computer and use it in GitHub Desktop.
data IdType = One | Two | Three
deriving (Eq, Ord, Enum, Bounded)
genSingletons [''IdType]
type ID = Int
-- | Simplest newtype implementaion almost everithing can be derived
-- without defining handwritten instances. Can be stored in heterogeneous
-- collections
newtype CompoundID = CompoundID (IdType,ID)
deriving (Eq, Ord)
instance Show IntfName where
shows (CompoundID (t, iD)) = show t ++ '/':show iD
-- | Typed implementation usefull for prcocessing in id type specific
-- functions. This is newtype and newtype deriving is still possible
newtype TypedID (t::IdType) = TypedID ID
deriving (Eq, Ord)
instance forall (t::IdType). (SingI t) => Show (IntfName' t) where
show (TypedID v) = show (fromSing $ sing @t) ++ '/':show v
-- | Existential wrapper for TypedID. newtype is not compatible with existential
-- types. So many biolerplate and probably worth perfomance comparing to CompoundID.
data ExistID = forall (t::IdType) . (SingI t) => ExistID (TypedID t)
getIDType :: ExistID -> IdType
getIDType (ExistID tv) = getIDType' sing tv
where
getIDType' :: forall (t::IdType). Sing t -> TypedID t -> IdType
getIDType' s _ = fromSing s
getID :: ExistID -> ID
getID (ExistID (TypedID v)) = v
instance Eq ExistID where
(==) :: ExistID -> ExistID -> Bool
(==) l r = getIDType l == getIDType r && getID l == getID r
instance Show ExistID where
show (ExistID tv) = show tv
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment