Created
November 7, 2019 10:43
-
-
Save drchaos/6823545972cf18ca2fd6b3500b2ce1bd to your computer and use it in GitHub Desktop.
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
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