{-# LANGUAGE Rank2Types #-} {- | Module : Numeric.VariablePrecision.Precision.Reify Copyright : (c) Claude Heiland-Allen 2012 License : BSD3 Maintainer : claude@mathr.co.uk Stability : unstable Portability : Rank2Types Reify from value-level to type-level using Rank2Types. -} module Numeric.VariablePrecision.Precision.Reify ( reifyPrecision , withReifiedPrecision , (.@$) ) where import Numeric.VariablePrecision.Precision ( VariablePrecision, withPrecision, Word , NaturalNumber, n0, successorTo ) -- | Reify a precision from value-level to type-level. reifyPrecision :: Word -> (forall p . NaturalNumber p => p -> a) -> a -- Implemented as described in an email from Gregory Grosswhite -- reifyPrecision = go n0 where go :: NaturalNumber q => q -> Word -> (forall p . NaturalNumber p => p -> a) -> a go n i f | i == 0 = f n | otherwise = go (successorTo n) (i - 1) f -- | Much like 'reifyPrecision' combined with 'withPrecision'. withReifiedPrecision :: (VariablePrecision t, NaturalNumber p) => t p {-^ original value -} -> Word {- ^ new precision -} -> (forall q. NaturalNumber q => t q -> a) {-^ operation -} -> a withReifiedPrecision x i f = reifyPrecision i (f . withPrecision x) infixl 1 `withReifiedPrecision` -- | An alias for 'withReifiedPrecision'. (.@$) :: (VariablePrecision t, NaturalNumber p) => t p {-^ original value -} -> Word {- ^ new precision -} -> (forall q. NaturalNumber q => t q -> a) {-^ operation -} -> a (.@$) = withReifiedPrecision infixl 1 .@$