Skip to content

Commit 75ae8e1

Browse files
committed
Add withBounds helper
1 parent b568a30 commit 75ae8e1

File tree

5 files changed

+147
-168
lines changed

5 files changed

+147
-168
lines changed

src/lib/Finite.hs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,10 @@
2929

3030
module Finite
3131
( -- * The Finite Class
32-
Finite(..)
32+
FiniteBounds
33+
, Finite(..)
3334
, GFinite(..)
34-
, FiniteBounds
35+
, withBounds
3536
, -- * Powersets
3637
PowerSet
3738
, -- * Collections
@@ -44,6 +45,7 @@ import Finite.Class
4445
( FiniteBounds
4546
, Finite(..)
4647
, GFinite(..)
48+
, withBounds
4749
)
4850

4951
import Finite.PowerSet

src/lib/Finite/Class.hs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
, MultiParamTypeClasses
1919
, TypeOperators
2020
, ScopedTypeVariables
21+
, RankNTypes
2122
, RequiredTypeArguments
2223
, ViewPatterns
2324

@@ -29,6 +30,7 @@ module Finite.Class
2930
( FiniteBounds
3031
, Finite(..)
3132
, GFinite(..)
33+
, withBounds
3234
) where
3335

3436
-----------------------------------------------------------------------------
@@ -59,11 +61,16 @@ import qualified Data.IntSet as S
5961
-----------------------------------------------------------------------------
6062

6163
-- | A better looking constraint specifier.
62-
6364
type FiniteBounds b = (?bounds :: b)
6465

6566
-----------------------------------------------------------------------------
6667

68+
-- | A more ergonomic way to set the implicit parameter.
69+
withBounds :: b -> (FiniteBounds b => c) -> c
70+
withBounds b x = let ?bounds = b in x
71+
72+
-----------------------------------------------------------------------------
73+
6774
-- | The 'Finite' class.
6875
class Finite b a where
6976
-- | Returns the number of elements associated with the given type.
@@ -106,7 +113,6 @@ class Finite b a where
106113
n = elements a
107114
o = offset a
108115

109-
110116
-- | Complements a given list of elements of that type
111117
complement :: FiniteBounds b => [a] -> [a]
112118
complement xs = value <$> ys

src/lib/Finite/Collection.hs

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import Finite.Class
2929
, offset
3030
, value
3131
, index
32+
, withBounds
3233
)
3334

3435
import Data.Array.IArray
@@ -70,9 +71,7 @@ data Collection i a = Item i a
7071
-- finite sized array of bounding parameters, it is guaranteed that
7172
-- the connected collection has a finite bound as well.
7273
instance (Ix i, Finite b a) => Finite (Array i b) (Collection i a) where
73-
elements _ = sum $ elms . snd <$> assocs ?bounds
74-
where
75-
elms b = let ?bounds = b in elements a
74+
elements _ = sum $ (`withBounds` elements a) . snd <$> assocs ?bounds
7675

7776
index (Item j v) = o + idx
7877
where
@@ -81,23 +80,22 @@ instance (Ix i, Finite b a) => Finite (Array i b) (Collection i a) where
8180
-- list of indicies that appear before j
8281
ys = assert (inRange (l, u) j) $ init $ range (l, j)
8382
-- offset induces by these indices
84-
o = sum $ map (elms . (?bounds !)) ys
83+
o = sum $ map ((`withBounds` elements a) . (?bounds !)) ys
8584
-- index of v with the bounds at position j
86-
idx = let ?bounds = ?bounds ! j in index v - offset a
87-
88-
elms b = let ?bounds = b in elements a
85+
idx = withBounds (?bounds ! j) $ index v - offset a
8986

9087
value n =
9188
assert (n >= 0 && n < elements (Collection i a))
92-
$ let ?bounds = ?bounds ! j in Item j $ value (m + offset a)
89+
$ withBounds (?bounds ! j) $ Item j $ value (m + offset a)
9390
where
9491
-- target array index and reminder used as sub-index
9592
(j, m) = position n $ range $ bounds ?bounds
9693

9794
position n = \case
98-
[] -> assert False undefined
99-
x:xr ->
100-
let m = let ?bounds = ?bounds ! x in elements a
101-
in if m <= n then position (n - m) xr else (x, n)
95+
[] -> assert False undefined
96+
x : xr | m <= n -> position (n - m) xr
97+
| otherwise -> (x, n)
98+
where
99+
m = withBounds (?bounds ! x) $ elements a
102100

103101
-----------------------------------------------------------------------------

src/lib/Finite/TH.hs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ import Data.Hashable
5353
import Finite.Class
5454
( FiniteBounds
5555
, Finite(..)
56+
, withBounds
5657
)
5758

5859
import Data.Char
@@ -591,28 +592,24 @@ appBounds x = x ?bounds
591592
elementsSwitch ::
592593
(Finite b' a, FiniteBounds b) => (b -> b') ->
593594
Finite b a => forall c -> (c ~ a, FiniteBounds b) => Int
594-
elementsSwitch f x =
595-
let ?bounds = f ?bounds
596-
in elements x
595+
elementsSwitch f x = withBounds (f ?bounds) $ elements x
597596

598597
-----------------------------------------------------------------------------
599598

600599
offsetSwitch ::
601600
(Finite b' a, FiniteBounds b) => (b -> b') ->
602601
Finite b a => forall c -> (c ~ a, FiniteBounds b) => Int
603-
offsetSwitch f x =
604-
let ?bounds = f ?bounds
605-
in offset x
602+
offsetSwitch f x = withBounds (f ?bounds) $ offset x
606603

607604
-----------------------------------------------------------------------------
608605

609606
indexSwitch :: (Finite b' a, FiniteBounds b) => (b -> b') -> a -> Int
610-
indexSwitch f = let ?bounds = f ?bounds in index
607+
indexSwitch f = withBounds (f ?bounds) index
611608

612609
-----------------------------------------------------------------------------
613610

614611
valueSwitch :: (Finite b' a, FiniteBounds b) => (b -> b') -> Int -> a
615-
valueSwitch f = let ?bounds = f ?bounds in value
612+
valueSwitch f = withBounds (f ?bounds) value
616613

617614
-----------------------------------------------------------------------------
618615

0 commit comments

Comments
 (0)