Untitled
unknown
haskell
4 years ago
1.5 kB
36
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 NothingEditor is loading...