Untitled
unknown
haskell
3 years ago
1.5 kB
32
Indexable
{-# LANGUAGE DataKinds #-} {-# LANGUAGE KindSignatures #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE GADTs #-} module Bank where import Data.Text data AccountKind = A | B | C deriving Show data AccountId (kind :: AccountKind) where AccountAId :: Text -> AccountId 'A -- I find this approach better because you can have -- different "info" types for each account type, -- which is most likely a requirement already because -- it's hard to imagine different account types don't have -- different invariants data AccountAInfo = AccountAInfo data AccountBInfo = AccountBInfo data Account (kind :: AccountKind) where AccountA :: AccountId 'A -> AccountAInfo -> Account 'A AccountB :: AccountId 'B -> AccountBInfo -> Account 'B -- You could also explore something with type families -- class Account acc where -- data AccountId acc :: Type -- data AccountInfo acc :: Type -- It's only possible to call this with `AccountA` specificAccountOperation :: Monad m => Account 'A -> m () specificAccountOperation (AccountA id info) = return () -- You'll receive a warning if you forget to handle an account type anyAccountOperation :: Monad m => Account kind -> m () anyAccountOperation (AccountA id info) = return () anyAccountOperation (AccountB id info) = return () lookupAccount :: Monad m => AccountId kind -> m (Maybe (Account kind)) lookupAccount accId = do -- You can choose how to serialize/deserialize -- your account ids via typeclass isntances -- in order to do a lookup (e.g. database, in-memory) return Nothing
Editor is loading...