Skip to content

Commit 8109065

Browse files
Introduce clamp, extent and range
1 parent fa3f258 commit 8109065

File tree

2 files changed

+56
-18
lines changed

2 files changed

+56
-18
lines changed

src/Data/Array/AtLeast.purs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ module Data.Array.ArrayAL
2121
, append
2222
, appendArray
2323
, prependArray
24+
, range
2425
, concat
2526
, intersperse
2627

@@ -68,7 +69,7 @@ import Data.FastVect.FastVect as FV
6869
import Data.Foldable (class Foldable)
6970
import Data.FoldableWithIndex (class FoldableWithIndex)
7071
import Data.FunctorWithIndex (class FunctorWithIndex)
71-
import Data.Int.AtLeast (IntAL, fromInt')
72+
import Data.Int.AtLeast (IntAL, fromInt', toInt)
7273
import Data.Maybe (Maybe(Nothing, Just), fromJust)
7374
import Data.Reflectable (class Reflectable, reflectType)
7475
import Data.Semigroup.Foldable (class Foldable1, foldMap1DefaultL)
@@ -249,6 +250,19 @@ appendArray (ArrayAL xs) ys = ArrayAL $ xs <> ys
249250
prependArray :: (n :: Int) (a :: Type). Array a -> ArrayAL n a -> ArrayAL n a
250251
prependArray xs (ArrayAL ys) = ArrayAL $ xs <> ys
251252

253+
-- | Construct an `ArrayAL 1` of `IntAL min`, starting with the (type-level)
254+
-- | minimum `min` and ending with the runtime value of the `IntAL min`
255+
range
256+
:: (min :: Int). Reflectable min Int => IntAL min -> ArrayAL 1 (IntAL min)
257+
range i = ArrayAL $ toIntAL <$> values
258+
where
259+
260+
toIntAL :: Int -> IntAL min
261+
toIntAL j = unsafePartial $ fromInt' j
262+
263+
values :: Array Int
264+
values = Array.range (reflectType (Proxy :: _ min)) (toInt i)
265+
252266
concat
253267
:: (m :: Int) (n :: Int) (mn :: Int) (a :: Type)
254268
. Compare (-1) m LT

src/Data/Int/AtLeast.purs

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
module Data.Int.AtLeast
2-
( IntAL -- Constructor not exported. Use fromInt or fromInt'
2+
( IntAL -- Constructor not exported. Use fromInt, fromInt' or clamp
33
, fromInt
44
, fromInt'
5+
, clamp
56
, toInt
67
, toNumber
7-
, (%+%), plus
8-
, (%-%), minus
9-
, (%*%), times
10-
, (%/%), quotient
8+
, extent
9+
, (%+%)
10+
, plus
11+
, (%-%)
12+
, minus
13+
, (%*%)
14+
, times
15+
, (%/%)
16+
, quotient
1117
, modulo
1218
, remainder
1319
, divide
@@ -54,34 +60,47 @@ instance Reflectable min Int => Enum (IntAL min) where
5460
if n > reflectType (Proxy :: _ min) then Just (IntAL $ n - 1) else Nothing
5561

5662
instance Reflectable min Int => Show (IntAL min) where
57-
show (IntAL i) = "IntAL " <> show (reflectType (Proxy :: _ min)) <> " " <> show i
63+
show (IntAL i) = "IntAL " <> show (reflectType (Proxy :: _ min)) <> " " <>
64+
show i
5865

5966
instance Reflectable min Int => Arbitrary (IntAL min) where
6067
arbitrary =
6168
let
6269
n = reflectType (Proxy :: _ min)
6370
in
64-
IntAL <$> oneOf (NEA.cons'
65-
( elements $ NEA.singleton n )
66-
[ chooseInt (n + 1) (n + 10)
67-
, chooseInt (n + 11) (n + 100)
68-
, chooseInt (n + 101) (n + 10000)
69-
])
71+
IntAL <$> oneOf
72+
( NEA.cons'
73+
(elements $ NEA.singleton n)
74+
[ chooseInt (n + 1) (n + 10)
75+
, chooseInt (n + 11) (n + 100)
76+
, chooseInt (n + 101) (n + 10000)
77+
]
78+
)
7079

7180
-- | Convert an `Int` to an `IntAL min`, returning `Nothing` if the runtime
7281
-- | value of the input is smaller than `min`
7382
fromInt :: (min :: Int). Reflectable min Int => Int -> Maybe (IntAL min)
74-
fromInt i = if i >= reflectType (Proxy :: _ min) then Just (IntAL i) else Nothing
83+
fromInt i =
84+
if i >= reflectType (Proxy :: _ min) then Just (IntAL i) else Nothing
7585

7686
-- | A partial function, converting an `Int` to an `IntAL min`. Crashes at
7787
-- | runtime if the runtime value of the input is smaller than `min`
7888
fromInt'
7989
:: (min :: Int). Reflectable min Int => Partial => Int -> IntAL min
8090
fromInt' i =
81-
if i >= reflectType (Proxy :: _ min) then IntAL i
82-
else
83-
crashWith $ "Cannot convert Int " <> show i <> " to IntAL " <>
84-
show (reflectType (Proxy :: _ min))
91+
let
92+
minInt = reflectType (Proxy :: _ min)
93+
in
94+
if i >= minInt then IntAL i
95+
else crashWith $
96+
"Cannot convert Int " <> show i <> " to IntAL " <> show minInt
97+
98+
clamp :: (min :: Int). Reflectable min Int => Int -> IntAL min
99+
clamp i =
100+
let
101+
minInt = reflectType (Proxy :: _ min)
102+
in
103+
if i >= minInt then IntAL i else IntAL minInt
85104

86105
-- | Convert an `IntAL` to an `Int`
87106
toInt :: (min :: Int). IntAL min -> Int
@@ -91,6 +110,11 @@ toInt (IntAL i) = i
91110
toNumber :: (min :: Int). IntAL min -> Number
92111
toNumber (IntAL i) = Int.toNumber i
93112

113+
-- | Measure the distance between the runtime value of an `IntAL min` and the
114+
-- | type-level minimum value `min`, as an IntAL 0
115+
extent :: (min :: Int). Reflectable min Int => IntAL min -> IntAL 0
116+
extent (IntAL i) = IntAL $ reflectType (Proxy :: _ min) - i
117+
94118
-- | Add two IntAL values with possibly different type-level minimums
95119
plus
96120
:: (min_i :: Int) (min_j :: Int) (min_sum :: Int)

0 commit comments

Comments
 (0)