Skip to content

Instantly share code, notes, and snippets.

@tim2CF
Created December 4, 2020 22:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tim2CF/221616992d89d9ef458df8080bfa4a28 to your computer and use it in GitHub Desktop.
Save tim2CF/221616992d89d9ef458df8080bfa4a28 to your computer and use it in GitHub Desktop.
KindedTypeParameters.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE KindSignatures #-}
module Lib where
data Owner = Merchant | Customer
newtype MoneyAmount (a :: Owner)
= MoneyAmount Rational
data BalanceCurrency
= BX
| BY
| BZ
data SettlmentCurrency
= SX
| SY
--
-- How I can add constraint to type `b`?
-- I want it to be only `BalanceCurrency` or `SettlementCurrency`.
-- But not any other type.
--
data Money (a :: Owner) b
= Money
{ amt :: MoneyAmount a,
cc :: b
}
@tim2CF
Copy link
Author

tim2CF commented Dec 5, 2020

{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}

module Lib where

data Owner = Merchant | Customer

newtype MoneyAmount (a :: Owner)
  = MoneyAmount Rational

data Balance
  = B_EUR
  | B_USD
  | B_BTC
  | B_LTC

data Settlement
  = S_BTC
  | S_LTC

class Currency a

instance Currency Balance

instance Currency Settlement

data Money (a :: Owner) b where
  Money :: Currency b => {amt :: MoneyAmount a, cc :: b} -> Money a b

x0 :: Money Merchant Balance
x0 = Money {amt = MoneyAmount 1, cc = B_EUR}

x1 :: Money Merchant Settlement
x1 = Money {amt = MoneyAmount 1, cc = S_BTC}

x2 :: Money Customer Balance
x2 = Money {amt = MoneyAmount 1, cc = B_EUR}
-- this will not compile
--x3 :: Money Customer String
--x3 = Money {amt = MoneyAmount 1, cc = "B_EUR"}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment