variable-precision-0.2: Numeric/VariablePrecision/Precision/Reify.hs
{-# LANGUAGE Rank2Types #-}
{- |
Module : Numeric.VariablePrecision.Precision.Reify
Copyright : (c) Claude Heiland-Allen 2012
License : BSD3
Maintainer : claudiusmaximus@goto10.org
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
-- <http://markmail.org/message/55iuty6axeljj2do>
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 .@$