diff options
author | Ashley Yakeley <ashley@semantic.org> | 2019-03-11 13:02:13 -0700 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2019-07-13 16:35:41 -0400 |
commit | a31b24a591aecc734449d3af479e3a3d1834b0ed (patch) | |
tree | 34f7383cbf300a769d1868d71f6e5ff49d527a51 /libraries | |
parent | de3935a6ccc26ec063e13d2739dd098c7616fde2 (diff) | |
download | haskell-a31b24a591aecc734449d3af479e3a3d1834b0ed.tar.gz |
base: Data.Fixed: make HasResolution poly-kinded (#10055, #15622)
Diffstat (limited to 'libraries')
-rw-r--r-- | libraries/base/Data/Fixed.hs | 19 | ||||
-rw-r--r-- | libraries/base/changelog.md | 4 |
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* |