summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAshley Yakeley <ashley@semantic.org>2019-03-11 13:02:13 -0700
committerMarge Bot <ben+marge-bot@smart-cactus.org>2019-07-13 16:35:41 -0400
commita31b24a591aecc734449d3af479e3a3d1834b0ed (patch)
tree34f7383cbf300a769d1868d71f6e5ff49d527a51
parentde3935a6ccc26ec063e13d2739dd098c7616fde2 (diff)
downloadhaskell-a31b24a591aecc734449d3af479e3a3d1834b0ed.tar.gz
base: Data.Fixed: make HasResolution poly-kinded (#10055, #15622)
-rw-r--r--libraries/base/Data/Fixed.hs19
-rw-r--r--libraries/base/changelog.md4
2 files changed, 17 insertions, 6 deletions
diff --git a/libraries/base/Data/Fixed.hs b/libraries/base/Data/Fixed.hs
index 482ec0a694..e99efea256 100644
--- a/libraries/base/Data/Fixed.hs
+++ b/libraries/base/Data/Fixed.hs
@@ -1,5 +1,7 @@
{-# LANGUAGE Trustworthy #-}
{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE FlexibleInstances #-}
-----------------------------------------------------------------------------
-- |
@@ -37,6 +39,7 @@ module Data.Fixed
) where
import Data.Data
+import GHC.TypeLits (KnownNat, natVal)
import GHC.Read
import Text.ParserCombinators.ReadPrec
import Text.Read.Lex
@@ -58,7 +61,7 @@ mod' n d = n - (fromInteger f) * d where
f = div' n d
-- | The type parameter should be an instance of 'HasResolution'.
-newtype Fixed a = MkFixed Integer
+newtype Fixed (a :: k) = MkFixed Integer
deriving ( Eq -- ^ @since 2.01
, Ord -- ^ @since 2.01
)
@@ -71,17 +74,21 @@ conMkFixed :: Constr
conMkFixed = mkConstr tyFixed "MkFixed" [] Prefix
-- | @since 4.1.0.0
-instance (Typeable a) => Data (Fixed a) where
+instance (Typeable k,Typeable a) => Data (Fixed (a :: k)) where
gfoldl k z (MkFixed a) = k (z MkFixed) a
gunfold k z _ = k (z MkFixed)
dataTypeOf _ = tyFixed
toConstr _ = conMkFixed
-class HasResolution a where
+class HasResolution (a :: k) where
resolution :: p a -> Integer
-withType :: (p a -> f a) -> f a
-withType foo = foo undefined
+-- | For example, @Fixed 1000@ will give you a 'Fixed' with a resolution of 1000.
+instance KnownNat n => HasResolution n where
+ resolution _ = natVal (Proxy :: Proxy n)
+
+withType :: (Proxy a -> f a) -> f a
+withType foo = foo Proxy
withResolution :: (HasResolution a) => (Integer -> f a) -> f a
withResolution foo = withType (foo . resolution)
@@ -170,7 +177,7 @@ convertFixed :: forall a . HasResolution a => Lexeme -> ReadPrec (Fixed a)
convertFixed (Number n)
| Just (i, f) <- numberToFixed e n =
return (fromInteger i + (fromInteger f / (10 ^ e)))
- where r = resolution (undefined :: Fixed a)
+ where r = resolution (Proxy :: Proxy a)
-- round 'e' up to help make the 'read . show == id' property
-- possible also for cases where 'resolution' is not a
-- power-of-10, such as e.g. when 'resolution = 128'
diff --git a/libraries/base/changelog.md b/libraries/base/changelog.md
index 5256730529..8cb3366dd2 100644
--- a/libraries/base/changelog.md
+++ b/libraries/base/changelog.md
@@ -21,6 +21,10 @@
The type argument `r` is marked as `Inferred` to prevent it from
interfering with visible type application.
+ * Make `Fixed` and `HasResolution` poly-kinded.
+
+ * Add `HasResolution` instances for `Nat`s.
+
## 4.13.0.0 *TBA*
* Bundled with GHC *TBA*