@@ -156,8 +156,15 @@ natEnumFromTo n m = if n <= m
156total natEnumFromThenTo' : Nat -> Nat -> Nat -> List Nat
156total natEnumFromThenTo' : Nat -> Nat -> Nat -> List Nat
157natEnumFromThenTo' _ Z _ = []
157natEnumFromThenTo' _ Z _ = []
158natEnumFromThenTo' n (S inc) m = map (plus n . (* (S inc))) (natRange (S (divNatNZ (minus m n) (S inc) SIsNotZ)))
158natEnumFromThenTo' n (S inc) m = map (plus n . (* (S inc))) (natRange (S (divNatNZ (minus m n) (S inc) SIsNotZ)))
159total natEnumFromThenTo : Nat -> Nat -> Nat -> List Nat
160total natEnumFromThenTo : Nat -> Nat -> Nat -> List Nat
161+natEnumFromThenTo n next m = if n == m then [n]
160−natEnumFromThenTo n next m = natEnumFromThenTo' n (minus next n) m
162+ else if n < m then natEnumFromThenTo' n (minus next n) m
163+ else case minus n next of
165+ S step => List.reverse . map (+ (modNatNZ (minus n m) (S step) SIsNotZ)) $ natEnumFromThenTo' m (minus n next) n
166+ where modNatNZ : Nat -> (m : Nat) -> Not (m = 0) -> Nat
167+ modNatNZ n m nz = minus n $ mult m $ divNatNZ n m nz
162interface Enum a where
169interface Enum a where
163 total pred : a -> a
170 total pred : a -> a
@@ -197,8 +204,9 @@ Enum Integer where
197 go' n (x :: xs) = n + cast x :: go' n xs
204 go' n (x :: xs) = n + cast x :: go' n xs
198 go : Integer -> Integer -> List Integer
205 go : Integer -> Integer -> List Integer
199 go n m = go' n (natRange (S (cast {to = Nat} (m - n))))
206 go n m = go' n (natRange (S (cast {to = Nat} (m - n))))
200− enumFromThenTo _ 0 _ = []
207+ enumFromThenTo n next m = if n == m then [n]
208+ else if next - n == 0 || next - n < 0 /= m - n < 0 then []
201− enumFromThenTo n next m = go (natRange (S (divNatNZ (fromInteger (abs (m - n))) (S (fromInteger ((abs (next - n)) - 1))) SIsNotZ)))
209+ else go (natRange (S (divNatNZ (fromInteger (abs (m - n))) (S (fromInteger ((abs (next - n)) - 1))) SIsNotZ)))
202 where go : List Nat -> List Integer
210 where go : List Nat -> List Integer
203 go [] = []
211 go [] = []
204 go (x :: xs) = n + (cast x * (next - n)) :: go xs
212 go (x :: xs) = n + (cast x * (next - n)) :: go xs
@@ -217,8 +225,9 @@ Enum Int where
217 go : Int -> Int -> List Int
225 go : Int -> Int -> List Int
218 go n m = go' [] (cast {to = Nat} (m - n)) m
226 go n m = go' [] (cast {to = Nat} (m - n)) m
219 enumFromThen n inc = n :: enumFromThen (inc + n) inc
227 enumFromThen n inc = n :: enumFromThen (inc + n) inc
220− enumFromThenTo _ 0 _ = []
228+ enumFromThenTo n next m = if n == m then [n]
229+ else if next - n == 0 || next - n < 0 /= m - n < 0 then []
221− enumFromThenTo n next m = go (natRange (S (divNatNZ (cast {to=Nat} (abs (m - n))) (S (cast {to=Nat} ((abs (next - n)) - 1))) SIsNotZ)))
230+ else go (natRange (S (divNatNZ (cast {to=Nat} (abs (m - n))) (S (cast {to=Nat} ((abs (next - n)) - 1))) SIsNotZ)))
222 where go : List Nat -> List Int
231 where go : List Nat -> List Int
223 go [] = []
232 go [] = []
224 go (x :: xs) = n + (cast x * (next - n)) :: go xs
233 go (x :: xs) = n + (cast x * (next - n)) :: go xs