Skip to content

Commit 4dbd9cd

Browse files
Fix 'fromIndex' internal helper (#23)
* Fix 'fromIndex' internal helper * Bump build dependencies * Add `Cons a Nil` case for `fromIndex` Co-authored-by: JordanMartinez <jordanalex.martinez@gmail.com>
1 parent 4bed79a commit 4dbd9cd

File tree

2 files changed

+17
-17
lines changed

2 files changed

+17
-17
lines changed

src/Control/Monad/Gen.purs

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@ import Prelude
1313

1414
import Control.Monad.Gen.Class (class MonadGen, Size, chooseBool, chooseFloat, chooseInt, resize, sized)
1515
import Control.Monad.Rec.Class (class MonadRec, Step(..), tailRecM)
16-
import Data.Foldable (foldMap, length)
16+
import Data.Foldable (foldMap, foldr, length)
1717
import Data.Maybe (Maybe(..))
1818
import Data.Monoid.Additive (Additive(..))
19-
import Data.Newtype (alaF)
19+
import Data.Newtype (alaF, un)
2020
import Data.Semigroup.Foldable (class Foldable1, foldMap1)
21+
import Data.Semigroup.Last (Last(..))
2122
import Data.Tuple (Tuple(..), fst, snd)
2223
import Data.Unfoldable (class Unfoldable, unfoldr)
2324

@@ -118,22 +119,14 @@ filtered gen = tailRecM go unit
118119
Nothing -> Loop unit
119120
Just a' -> Done a'
120121

121-
-- | Internal: used by fromIndex
122-
newtype AtIndex a = AtIndex (Int -> a)
123-
124-
instance semigroupAtIndex :: Semigroup (AtIndex a)
125-
where
126-
append (AtIndex f) (AtIndex g) =
127-
AtIndex \i -> if i <= 0 then f i else g (i - 1)
128-
129-
atIndex :: forall a. a -> AtIndex a
130-
atIndex = AtIndex <<< const
131-
132-
getAtIndex :: forall a. AtIndex a -> Int -> a
133-
getAtIndex (AtIndex f) = f
134-
135122
-- | Internal: get the Foldable element at index i.
136123
-- | If the index is <= 0, return the first element.
137124
-- | If it's >= length, return the last.
138125
fromIndex :: forall f a. Foldable1 f => Int -> f a -> a
139-
fromIndex i xs = getAtIndex (foldMap1 atIndex xs) i
126+
fromIndex i xs = go i (foldr Cons Nil xs)
127+
where
128+
go _ (Cons a Nil) = a
129+
go j (Cons a _) | j <= 0 = a
130+
go j (Cons _ as) = go (j - 1) as
131+
-- next case is "impossible", but serves as proof of non-emptyness
132+
go _ Nil = un Last (foldMap1 Last xs)

test/Main.purs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@ main = do
3232
log "`genNonEmpty` should not reduce the remainder size below zero"
3333
one :: NonEmpty Array IntGen.resize (const 0) $ GenC.genNonEmpty (Gen.sized pure)
3434
liftEffect $ assertEqual { actual: one, expected: 0 :| [] }
35+
36+
log "Ensure that `elements` will produce all possible values (tests will hang if this fails)"
37+
_ ← Gen.suchThat (Gen.elements ("A" :| ["B", "C", "D"])) (_ == "A")
38+
_ ← Gen.suchThat (Gen.elements ("A" :| ["B", "C", "D"])) (_ == "B")
39+
_ ← Gen.suchThat (Gen.elements ("A" :| ["B", "C", "D"])) (_ == "C")
40+
_ ← Gen.suchThat (Gen.elements ("A" :| ["B", "C", "D"])) (_ == "D")
41+
pure unit
3542

3643
log "check frequency"
3744
Frequency.check

0 commit comments

Comments
 (0)