Skip to content

Commit d32f24c

Browse files
committed
tags refactoring
1 parent b97578d commit d32f24c

File tree

2 files changed

+90
-86
lines changed

2 files changed

+90
-86
lines changed

pub/functora/src/money/Functora/Money.hs

Lines changed: 77 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
module Functora.Money
44
( module X,
5-
MoneyRep,
5+
IntRep,
66
MoneyTags,
77
NewMoneyTags,
88
Money,
@@ -39,74 +39,69 @@ import Functora.Prelude
3939
import Functora.Tags as X
4040
import qualified Language.Haskell.TH.Syntax as TH
4141

42-
type family MoneyRep sig where
43-
MoneyRep 'Signed = Integer
44-
MoneyRep 'Unsigned = Natural
45-
46-
type MoneyTags (sig :: SignedOrUnsigned) tags =
47-
( GetTag sig tags,
48-
Eq (MoneyRep sig),
49-
Ord (MoneyRep sig),
50-
Show (MoneyRep sig),
51-
Read (MoneyRep sig),
52-
Data (MoneyRep sig),
53-
Integral (MoneyRep sig),
54-
From (MoneyRep sig) Integer,
55-
Typeable sig,
42+
type IntRep tags = NewIntRep (GetKey SignedOrUnsigned tags)
43+
44+
type family NewIntRep sig where
45+
NewIntRep 'Signed = Integer
46+
NewIntRep 'Unsigned = Natural
47+
48+
type MoneyTags tags =
49+
( Eq (IntRep tags),
50+
Ord (IntRep tags),
51+
Show (IntRep tags),
52+
Read (IntRep tags),
53+
Data (IntRep tags),
54+
Integral (IntRep tags),
55+
From (IntRep tags) Integer,
56+
Typeable (IntRep tags),
5657
Typeable tags
5758
)
5859

59-
type NewMoneyTags (sig :: SignedOrUnsigned) lhs rhs =
60+
type NewMoneyTags lhs rhs =
6061
( lhs ~ rhs,
61-
MoneyTags sig lhs
62+
MoneyTags lhs
6263
)
6364

6465
data Money tags where
6566
Money ::
66-
forall tags sig.
67-
( MoneyTags sig tags
67+
forall tags.
68+
( MoneyTags tags
6869
) =>
69-
Ratio (MoneyRep sig) ->
70+
Ratio (IntRep tags) ->
7071
Money tags
7172

7273
deriving stock instance Eq (Money tags)
7374

7475
deriving stock instance Ord (Money tags)
7576

76-
deriving stock instance (MoneyTags sig tags) => Show (Money tags)
77+
deriving stock instance (MoneyTags tags) => Show (Money tags)
7778

78-
deriving stock instance (MoneyTags sig tags) => Read (Money tags)
79+
deriving stock instance (MoneyTags tags) => Read (Money tags)
7980

80-
deriving stock instance (MoneyTags sig tags) => Data (Money tags)
81+
deriving stock instance (MoneyTags tags) => Data (Money tags)
8182

82-
unMoney ::
83-
forall tags sig.
84-
( MoneyTags sig tags
85-
) =>
86-
Money tags ->
87-
Ratio (MoneyRep sig)
83+
unMoney :: Money tags -> Ratio (IntRep tags)
8884
unMoney (Money x) = x
8985

9086
parseMoney ::
91-
forall str tags m sig rep.
87+
forall str tags m.
9288
( From str Text,
9389
Show str,
9490
Data str,
95-
MonadThrow m,
96-
MoneyTags sig tags,
97-
rep ~ MoneyRep sig
91+
MoneyTags tags,
92+
MonadThrow m
9893
) =>
9994
str ->
10095
m (Money tags)
10196
parseMoney =
10297
fmap Money . parseRatio
10398

10499
data SomeMoney k tags
105-
= forall (tag :: k) (sig :: SignedOrUnsigned).
100+
= forall (tag :: k).
106101
( SingI tag,
107102
Typeable tag,
108103
Typeable k,
109-
MoneyTags sig (tags |+| tag)
104+
MoneyTags (tags |+| tag)
110105
) =>
111106
SomeMoney
112107
(Sing tag)
@@ -121,17 +116,19 @@ instance (TestEquality (Sing :: k -> Type)) => Eq (SomeMoney k tags) where
121116
deriving stock instance Show (SomeMoney k tags)
122117

123118
newMoney ::
124-
forall tags sig.
125-
( MoneyTags sig tags
119+
forall tags.
120+
( MoneyTags tags
126121
) =>
127-
Ratio (MoneyRep sig) ->
122+
Ratio (IntRep tags) ->
128123
Money tags
129124
newMoney = Money
130125

131126
newUnsignedMoneyBOS ::
132127
forall tags buy sell.
133-
( NewMoneyTags 'Unsigned buy (tags |+| 'Unsigned |+| 'Buy),
134-
NewMoneyTags 'Unsigned sell (tags |+| 'Unsigned |+| 'Sell)
128+
( NewMoneyTags buy (tags |+| 'Unsigned |+| 'Buy),
129+
NewMoneyTags sell (tags |+| 'Unsigned |+| 'Sell),
130+
IntRep buy ~ Natural,
131+
IntRep sell ~ Natural
135132
) =>
136133
Rational ->
137134
SomeMoney BuyOrSell (tags |+| 'Unsigned)
@@ -143,8 +140,10 @@ newUnsignedMoneyBOS raw
143140

144141
newUnsignedMoneyGOL ::
145142
forall tags gain lose.
146-
( NewMoneyTags 'Unsigned gain (tags |+| 'Unsigned |+| 'Gain),
147-
NewMoneyTags 'Unsigned lose (tags |+| 'Unsigned |+| 'Lose)
143+
( NewMoneyTags gain (tags |+| 'Unsigned |+| 'Gain),
144+
NewMoneyTags lose (tags |+| 'Unsigned |+| 'Lose),
145+
IntRep gain ~ Natural,
146+
IntRep lose ~ Natural
148147
) =>
149148
Rational ->
150149
SomeMoney GainOrLose (tags |+| 'Unsigned)
@@ -155,21 +154,18 @@ newUnsignedMoneyGOL raw
155154
uns = unsafeFrom @Rational @(Ratio Natural) $ abs raw
156155

157156
newFeeRate ::
158-
forall prev sig next.
159-
( NewMoneyTags sig next (prev |+| 'FeeRate)
157+
forall prev next.
158+
( NewMoneyTags next (prev |+| 'FeeRate)
160159
) =>
161-
Ratio (MoneyRep sig) ->
160+
Ratio (IntRep next) ->
162161
Money next
163162
newFeeRate = Money
164163

165164
addFee ::
166-
forall fee amt sig tags.
167-
( GetTag sig fee,
168-
GetTag sig amt,
169-
NewMoneyTags
170-
sig
171-
tags
172-
((fee |-| sig |-| 'FeeRate) |&| (amt |-| 'Net |+| 'Gross))
165+
forall fee amt tags.
166+
( IntRep fee ~ IntRep amt,
167+
IntRep fee ~ IntRep tags,
168+
NewMoneyTags tags (amt |-| 'Net |+| 'Gross)
173169
) =>
174170
Money fee ->
175171
Money amt ->
@@ -178,12 +174,10 @@ addFee (Money fee) (Money amt) =
178174
Money $ amt / (1 - fee)
179175

180176
deductFee ::
181-
( GetTag sig fee,
182-
GetTag sig amt,
183-
NewMoneyTags
184-
sig
185-
tags
186-
((fee |-| sig |-| 'FeeRate) |&| (amt |-| 'Gross |+| 'Net))
177+
forall fee amt tags.
178+
( IntRep fee ~ IntRep amt,
179+
IntRep fee ~ IntRep tags,
180+
NewMoneyTags tags (amt |-| 'Gross |+| 'Net)
187181
) =>
188182
Money fee ->
189183
Money amt ->
@@ -192,13 +186,10 @@ deductFee (Money fee) (Money amt) =
192186
Money $ amt * (1 - fee)
193187

194188
exchangeMoney ::
195-
forall rate base quote sig.
196-
( MoneyTags sig rate,
197-
MoneyTags sig base,
198-
NewMoneyTags
199-
sig
200-
quote
201-
((rate |-| sig |-| 'QuotePerBase) |&| (base |-| 'Base |+| 'Quote))
189+
forall rate base quote.
190+
( IntRep rate ~ IntRep base,
191+
IntRep rate ~ IntRep quote,
192+
NewMoneyTags quote (base |-| 'Base |+| 'Quote)
202193
) =>
203194
Money rate ->
204195
Money base ->
@@ -207,13 +198,7 @@ exchangeMoney (Money rate) (Money base) =
207198
Money $ rate * base
208199

209200
data Funds tags where
210-
Funds ::
211-
forall tags sig.
212-
( MoneyTags sig tags
213-
) =>
214-
Money tags ->
215-
CurrencyCode ->
216-
Funds tags
201+
Funds :: Money tags -> CurrencyCode -> Funds tags
217202

218203
fundsMoneyAmount :: Funds tags -> Money tags
219204
fundsMoneyAmount (Funds amt _) = amt
@@ -225,17 +210,21 @@ deriving stock instance Eq (Funds tags)
225210

226211
deriving stock instance Ord (Funds tags)
227212

228-
deriving stock instance (MoneyTags sig tags) => Show (Funds tags)
213+
deriving stock instance (MoneyTags tags) => Show (Funds tags)
229214

230-
deriving stock instance (MoneyTags sig tags) => Read (Funds tags)
215+
deriving stock instance (MoneyTags tags) => Read (Funds tags)
231216

232-
deriving stock instance (MoneyTags sig tags) => Data (Funds tags)
217+
deriving stock instance (MoneyTags tags) => Data (Funds tags)
233218

234219
unJsonRational :: A.Decoder Rational
235-
unJsonRational =
236-
toRational <$> A.scientific
220+
unJsonRational = toRational <$> A.scientific
237221

238-
unJsonMoney :: forall tags sig. (MoneyTags sig tags) => A.Decoder (Money tags)
222+
unJsonMoney ::
223+
forall tags (sig :: SignedOrUnsigned).
224+
( MoneyTags tags,
225+
GetTag sig tags
226+
) =>
227+
A.Decoder (Money tags)
239228
unJsonMoney = do
240229
rat <- unJsonRational
241230
case sing :: Sing sig of
@@ -245,18 +234,22 @@ unJsonMoney = do
245234
$ tryFrom @Rational @(Ratio Natural) rat
246235

247236
unJsonUnsignedMoneyBOS ::
248-
forall tags.
249-
( MoneyTags 'Unsigned (tags |+| 'Unsigned |+| 'Buy),
250-
MoneyTags 'Unsigned (tags |+| 'Unsigned |+| 'Sell)
237+
forall tags buy sell.
238+
( NewMoneyTags buy (tags |+| 'Unsigned |+| 'Buy),
239+
NewMoneyTags sell (tags |+| 'Unsigned |+| 'Sell),
240+
IntRep buy ~ Natural,
241+
IntRep sell ~ Natural
251242
) =>
252243
A.Decoder (SomeMoney BuyOrSell (tags |+| 'Unsigned))
253244
unJsonUnsignedMoneyBOS =
254245
newUnsignedMoneyBOS @tags <$> unJsonRational
255246

256247
unJsonUnsignedMoneyGOL ::
257-
forall tags.
258-
( MoneyTags 'Unsigned (tags |+| 'Unsigned |+| 'Gain),
259-
MoneyTags 'Unsigned (tags |+| 'Unsigned |+| 'Lose)
248+
forall tags gain lose.
249+
( NewMoneyTags gain (tags |+| 'Unsigned |+| 'Gain),
250+
NewMoneyTags lose (tags |+| 'Unsigned |+| 'Lose),
251+
IntRep gain ~ Natural,
252+
IntRep lose ~ Natural
260253
) =>
261254
A.Decoder (SomeMoney GainOrLose (tags |+| 'Unsigned))
262255
unJsonUnsignedMoneyGOL =

pub/functora/src/tags/Functora/TagsFamily.hs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ module Functora.TagsFamily
1818
HasTag,
1919
HasTags,
2020
GetTag,
21+
GetKey,
22+
GetTagDef,
2123

2224
-- * Introspection
2325
-- $introspection
@@ -96,11 +98,15 @@ type HasTags sub sup =
9698
)
9799

98100
type GetTag (v :: k) tags =
99-
( Sing v ~ GetTagFamily k tags tags,
101+
( v ~ GetTagFamily k tags tags,
100102
SingI v,
101103
HasTag v tags
102104
)
103105

106+
type GetKey k tags = GetTagFamily k tags tags
107+
108+
type GetTagDef (def :: k) tags = GetTagDefFamily def tags tags
109+
104110
type family Fgpt (a :: k) :: Symbol
105111

106112
mkFgpt :: forall a. (Typeable a) => TH.Q [TH.Dec]
@@ -184,7 +190,7 @@ type family UnTagFamily member v tags prev next where
184190
UnTagFamily member v tags prev (kv ': next)
185191

186192
type family GetTagFamily k tags prev where
187-
GetTagFamily k _ ((k ':-> v) ': _) = v
193+
GetTagFamily k _ ((k ':-> Sing v) ': _) = v
188194
GetTagFamily k tags (_ ': next) = GetTagFamily k tags next
189195
GetTagFamily k tags '[] =
190196
TypeError
@@ -193,6 +199,11 @@ type family GetTagFamily k tags prev where
193199
':<>: 'ShowType tags
194200
)
195201

202+
type family GetTagDefFamily (def :: k) tags prev where
203+
GetTagDefFamily (_ :: k) _ ((k ':-> Sing v) ': _) = v
204+
GetTagDefFamily def tags (_ ': next) = GetTagDefFamily def tags next
205+
GetTagDefFamily def _ '[] = def
206+
196207
type family HasTagsFamily hastag submap supmap where
197208
HasTagsFamily 'Nothing '[] _ = 'True
198209
HasTagsFamily has '[] sup =

0 commit comments

Comments
 (0)