shithub: MicroHs

Download patch

ref: 5b6168bbba78656837ecb73c48ba207cd514d7ea
parent: c101325aaf8ed0ec3c8c4ff4b7d425bba799825a
author: konsumlamm <konsumlamm@gmail.com>
date: Wed Jan 8 10:57:27 EST 2025

Define helpers for `Enum` instances of numeric types

Add `Enum (Ratio a)` instance

--- a/lib/Data/Enum.hs
+++ b/lib/Data/Enum.hs
@@ -40,6 +40,25 @@
     i_n1 = fromEnum n1
     i_n2 = fromEnum n2
 
+numericEnumFrom :: (Num a) => a -> [a]
+numericEnumFrom n = n : numericEnumFrom (n + 1)
+
+numericEnumFromThen :: (Num a) => a -> a -> [a]
+numericEnumFromThen n m = from n
+  where
+    d = m - n
+    from i = i : from (i + d)
+
+numericEnumFromTo :: (Num a, Ord a) => a -> a -> [a]
+numericEnumFromTo l h = takeWhile (<= h) (numericEnumFrom l)
+
+numericEnumFromThenTo :: (Num a, Ord a) => a -> a -> a -> [a]
+numericEnumFromThenTo l m h =
+    if m > l then
+      takeWhile (<= h) (numericEnumFromThen l m)
+    else
+      takeWhile (>= h) (numericEnumFromThen l m)
+
 -- This instance is difficult to put in Data.Int,
 -- so it gets to live here.
 instance Enum Int where
@@ -47,16 +66,10 @@
   pred x = x - 1
   toEnum x = x
   fromEnum x = x
-  enumFrom n = n : enumFrom (n+1)
-  enumFromThen n m = from n
-    where d = m - n
-          from i = i : from (i+d)
-  enumFromTo l h = takeWhile (<= h) (enumFrom l)
-  enumFromThenTo l m h =
-    if m > l then
-      takeWhile (<= h) (enumFromThen l m)
-    else
-      takeWhile (>= h) (enumFromThen l m)
+  enumFrom = numericEnumFrom
+  enumFromThen = numericEnumFromThen
+  enumFromTo = numericEnumFromTo
+  enumFromThenTo = numericEnumFromThenTo
 
 -- Likewise for Bool
 instance Enum Bool where
--- a/lib/Data/Int/Instances.hs
+++ b/lib/Data/Int/Instances.hs
@@ -72,16 +72,10 @@
   pred x = x - 1
   toEnum = i8
   fromEnum = unI8
-  enumFrom n = n : enumFrom (n+1)
-  enumFromThen n m = from n
-    where d = m - n
-          from i = i : from (i+d)
-  enumFromTo l h = takeWhile (<= h) (enumFrom l)
-  enumFromThenTo l m h =
-    if m > l then
-      takeWhile (<= h) (enumFromThen l m)
-    else
-      takeWhile (>= h) (enumFromThen l m)
+  enumFrom = numericEnumFrom
+  enumFromThen = numericEnumFromThen
+  enumFromTo = numericEnumFromTo
+  enumFromThenTo = numericEnumFromThenTo
 
 instance Eq Int8 where
   (==) = cmp8 primIntEQ
@@ -162,16 +156,10 @@
   pred x = x - 1
   toEnum = i16
   fromEnum = unI16
-  enumFrom n = n : enumFrom (n+1)
-  enumFromThen n m = from n
-    where d = m - n
-          from i = i : from (i+d)
-  enumFromTo l h = takeWhile (<= h) (enumFrom l)
-  enumFromThenTo l m h =
-    if m > l then
-      takeWhile (<= h) (enumFromThen l m)
-    else
-      takeWhile (>= h) (enumFromThen l m)
+  enumFrom = numericEnumFrom
+  enumFromThen = numericEnumFromThen
+  enumFromTo = numericEnumFromTo
+  enumFromThenTo = numericEnumFromThenTo
 
 instance Eq Int16 where
   (==) = cmp16 primIntEQ
@@ -252,16 +240,10 @@
   pred x = x - 1
   toEnum = i32
   fromEnum = unI32
-  enumFrom n = n : enumFrom (n+1)
-  enumFromThen n m = from n
-    where d = m - n
-          from i = i : from (i+d)
-  enumFromTo l h = takeWhile (<= h) (enumFrom l)
-  enumFromThenTo l m h =
-    if m > l then
-      takeWhile (<= h) (enumFromThen l m)
-    else
-      takeWhile (>= h) (enumFromThen l m)
+  enumFrom = numericEnumFrom
+  enumFromThen = numericEnumFromThen
+  enumFromTo = numericEnumFromTo
+  enumFromThenTo = numericEnumFromThenTo
 
 instance Eq Int32 where
   (==) = cmp32 primIntEQ
@@ -340,16 +322,10 @@
   pred x = x - 1
   toEnum = i64
   fromEnum = unI64
-  enumFrom n = n : enumFrom (n+1)
-  enumFromThen n m = from n
-    where d = m - n
-          from i = i : from (i+d)
-  enumFromTo l h = takeWhile (<= h) (enumFrom l)
-  enumFromThenTo l m h =
-    if m > l then
-      takeWhile (<= h) (enumFromThen l m)
-    else
-      takeWhile (>= h) (enumFromThen l m)
+  enumFrom = numericEnumFrom
+  enumFromThen = numericEnumFromThen
+  enumFromTo = numericEnumFromTo
+  enumFromThenTo = numericEnumFromThenTo
 
 instance Eq Int64 where
   (==) = cmp64 primIntEQ
--- a/lib/Data/Integer.hs
+++ b/lib/Data/Integer.hs
@@ -93,16 +93,10 @@
   pred x = x - 1
   toEnum x = _intToInteger x
   fromEnum x = _integerToInt x
-  enumFrom n = n : enumFrom (n+1)
-  enumFromThen n m = from n
-    where d = m - n
-          from i = i : from (i+d)
-  enumFromTo l h = takeWhile (<= h) (enumFrom l)
-  enumFromThenTo l m h =
-    if m > l then
-      takeWhile (<= h) (enumFromThen l m)
-    else
-      takeWhile (>= h) (enumFromThen l m)
+  enumFrom = numericEnumFrom
+  enumFromThen = numericEnumFromThen
+  enumFromTo = numericEnumFromTo
+  enumFromThenTo = numericEnumFromThenTo
 
 ------------------------------------------------
 
--- a/lib/Data/Ratio.hs
+++ b/lib/Data/Ratio.hs
@@ -9,6 +9,7 @@
   ) where
 import Prelude()              -- do not import Prelude
 import Data.Bool
+import Data.Enum
 import Data.Eq
 import Data.Fractional
 import Data.Function
@@ -42,6 +43,16 @@
 -- NOTE. Experimentally, we extend this with:
 --  x/0 ==  1/0 when x > 0
 --  x/0 == -1/0 when x < 0
+
+instance (Integral a) => Enum (Ratio a) where
+  succ x         = x + 1
+  pred x         = x - 1
+  toEnum         = fromIntegral
+  fromEnum       = fromInteger . truncate
+  enumFrom       = numericEnumFrom
+  enumFromThen   = numericEnumFromThen
+  enumFromTo     = numericEnumFromTo
+  enumFromThenTo = numericEnumFromThenTo
 
 instance forall a . Eq a => Eq (Ratio a) where
   (x :% y) == (x' :% y')  =  x == x' && y == y'
--- a/lib/Data/Word.hs
+++ b/lib/Data/Word.hs
@@ -57,16 +57,10 @@
   pred x = x - 1
   toEnum = primIntToWord
   fromEnum = primWordToInt
-  enumFrom n = n : enumFrom (n+1)
-  enumFromThen n m = from n
-    where d = m - n
-          from i = i : from (i+d)
-  enumFromTo l h = takeWhile (<= h) (enumFrom l)
-  enumFromThenTo l m h =
-    if m > l then
-      takeWhile (<= h) (enumFromThen l m)
-    else
-      takeWhile (>= h) (enumFromThen l m)
+  enumFrom = numericEnumFrom
+  enumFromThen = numericEnumFromThen
+  enumFromTo = numericEnumFromTo
+  enumFromThenTo = numericEnumFromThenTo
 
 --------------------------------
 
@@ -154,16 +148,10 @@
   pred x = x - 1
   toEnum = w8 . primIntToWord
   fromEnum = primWordToInt . unW8
-  enumFrom n = n : enumFrom (n+1)
-  enumFromThen n m = from n
-    where d = m - n
-          from i = i : from (i+d)
-  enumFromTo l h = takeWhile (<= h) (enumFrom l)
-  enumFromThenTo l m h =
-    if m > l then
-      takeWhile (<= h) (enumFromThen l m)
-    else
-      takeWhile (>= h) (enumFromThen l m)
+  enumFrom = numericEnumFrom
+  enumFromThen = numericEnumFromThen
+  enumFromTo = numericEnumFromTo
+  enumFromThenTo = numericEnumFromThenTo
 
 instance Eq Word8 where
   (==) = cmp8 primWordEQ
@@ -245,17 +233,10 @@
   succ x = x + 1
   pred x = x - 1
   toEnum = w16 . primIntToWord
-  fromEnum = primWordToInt . unW16
-  enumFrom n = n : enumFrom (n+1)
-  enumFromThen n m = from n
-    where d = m - n
-          from i = i : from (i+d)
-  enumFromTo l h = takeWhile (<= h) (enumFrom l)
-  enumFromThenTo l m h =
-    if m > l then
-      takeWhile (<= h) (enumFromThen l m)
-    else
-      takeWhile (>= h) (enumFromThen l m)
+  enumFrom = numericEnumFrom
+  enumFromThen = numericEnumFromThen
+  enumFromTo = numericEnumFromTo
+  enumFromThenTo = numericEnumFromThenTo
 
 instance Eq Word16 where
   (==) = cmp16 primWordEQ
@@ -338,16 +319,10 @@
   pred x = x - 1
   toEnum = w32 . primIntToWord
   fromEnum = primWordToInt . unW32
-  enumFrom n = n : enumFrom (n+1)
-  enumFromThen n m = from n
-    where d = m - n
-          from i = i : from (i+d)
-  enumFromTo l h = takeWhile (<= h) (enumFrom l)
-  enumFromThenTo l m h =
-    if m > l then
-      takeWhile (<= h) (enumFromThen l m)
-    else
-      takeWhile (>= h) (enumFromThen l m)
+  enumFrom = numericEnumFrom
+  enumFromThen = numericEnumFromThen
+  enumFromTo = numericEnumFromTo
+  enumFromThenTo = numericEnumFromThenTo
 
 instance Eq Word32 where
   (==) = cmp32 primWordEQ
@@ -430,16 +405,10 @@
   pred x = x - 1
   toEnum = w64 . primIntToWord
   fromEnum = primWordToInt . unW64
-  enumFrom n = n : enumFrom (n+1)
-  enumFromThen n m = from n
-    where d = m - n
-          from i = i : from (i+d)
-  enumFromTo l h = takeWhile (<= h) (enumFrom l)
-  enumFromThenTo l m h =
-    if m > l then
-      takeWhile (<= h) (enumFromThen l m)
-    else
-      takeWhile (>= h) (enumFromThen l m)
+  enumFrom = numericEnumFrom
+  enumFromThen = numericEnumFromThen
+  enumFromTo = numericEnumFromTo
+  enumFromThenTo = numericEnumFromThenTo
 
 instance Eq Word64 where
   (==) = cmp64 primWordEQ