Untitled
unknown
haskell
2 years ago
1.7 kB
32
No Index
Never
{-# LANGUAGE DataKinds #-} import Control.Newtype (Newtype) import qualified Control.Newtype as Newtype import Witch (from) -- | A bank account ID for an account of some @accountKind@. newtype AccountID accountKind = AccountID Text instance Newtype (AccountID accountKind) Text -- | Bank account info for an account of some @accountKind@. newtype AccountInfo accountKind = AccountInfo Text instance Newtype (AccountInfo accountKind) Text -- | The different kinds of bank accounts. data AccountKind = A | B | C deriving Show -- | Demote the kind of bank account to the value level. class OfAccountKind (t :: AccountKind) where demoteAccountKind :: f t -> AccountKind -- Possible to derive these instances? Preferably without TH? instance OfAccountKind 'A where demoteAccountKind _ = A instance OfAccountKind 'B where demoteAccountKind _ = B instance OfAccountKind 'C where demoteAccountKind _ = C changeType :: (Newtype a inner, Newtype b inner) => a -> b changeType = Newtype.pack . Newtype.unpack -- | @AccountInfo@ for a bank account of some kind, looked up by @AccountID@. accountInfo :: OfAccountKind accountKind => AccountID accountKind -> Either Text (Maybe (AccountInfo accountKind)) accountInfo accountID = fmap (fmap changeType) $ case demoteAccountKind accountID of A -> Right $ accountAInfo $ changeType accountID x -> Left $ from $ "Unsupported AccountKind " <> show x -- | @AccountInfo@ for a bank account of kind @A@. accountAInfo :: AccountID 'A -> Maybe (AccountInfo 'A) accountAInfo _accountID = pure $ AccountInfo "Info found via lookup of '_accountID'"