{-# LANGUAGE Rank2Types #-} {- | Module : Numeric.VariablePrecision.Precision.Reify Copyright : (c) Claude Heiland-Allen 2012 License : BSD3 Maintainer : claudiusmaximus@goto10.org Stability : provisional Portability : Rank2Types Reify from value-level to type-level using Rank2Types. -} module Numeric.VariablePrecision.Precision.Reify ( reifyPrecision , withReifiedPrecision , (.@$) ) where import Numeric.VariablePrecision.Precision (NaturalNumber, n0, successorTo, VariablePrecision, withPrecision) -- | Reify a precision from value-level to type-level. reifyPrecision :: Int -> (forall p . NaturalNumber p => p -> a) -> a -- Implemented as described in an email from Gregory Grosswhite -- reifyPrecision = go n0 where go :: NaturalNumber q => q -> Int -> (forall p . NaturalNumber p => p -> a) -> a go n i f | i < 0 = error $ "Numeric.VariablePrecision.Precision.Reify.reifyPrecision: negative argument: " ++ show i | i == 0 = f n | i > 0 = go (successorTo n) (i - 1) f -- | Much like 'reifyPrecision' combined with 'withPrecision'. withReifiedPrecision :: (VariablePrecision t, NaturalNumber p) => t p {-^ original value -} -> Int {- ^ new precision -} -> (forall q. NaturalNumber q => t q -> a) {-^ operation -} -> a withReifiedPrecision x i f = reifyPrecision i (f . withPrecision x) infixl 1 `withReifiedPrecision` -- same fixity as Prelude.$ -- | An alias for 'withReifiedPrecision'. (.@$) :: (VariablePrecision t, NaturalNumber p) => t p {-^ original value -} -> Int {- ^ new precision -} -> (forall q. NaturalNumber q => t q -> a) {-^ operation -} -> a (.@$) = withReifiedPrecision infix 1 .@$ -- same fixity as Prelude.$