Skip to content

Internal module to expose constructor for Scientific #67

@MaxGabriel

Description

@MaxGabriel

Hi, I have a newtype over Scientific and I've made a quasi quoter for using it in an expression. However, I believe to make a quasi quoter to use it in a pattern context I would need access to the constructor. Would you be open to adding an Internal module that exposes the constructor for Scientific?

For reference, this is how I create Scientifics in an expression context:

instance Lift Scientific where
  lift sci = 
    let coefficient = Scientific.coefficient sci
        base10Exponent = Scientific.base10Exponent sci
    in [|Scientific.scientific $(TH.lift coefficient) $(TH.lift base10Exponent)|]

-- | Arbitrary-precision value constrained to 0 through 100, inclusive.
newtype Percentage = Percentage Scientific
  deriving (Eq, Show, Read, Ord, ToJSON, Num, Fractional, Real, RealFrac, Lift)

mkPercentage :: Scientific -> Maybe Percentage
mkPercentage sci = if sci >= 0 && sci <= 100 then Just (Percentage sci) else Nothing

-- | Create a 'Percentage' at compile time
-- Usage:
-- > [compilePercentage|100|]
compilePercentage :: QuasiQuoter
compilePercentage = QuasiQuoter
    { quoteExp = quoteExp'
    , quotePat = error "percentage is not supported as a pattern" -- I don't think this can be implemented without access to the Scientific constructor. Maybe with the Num instance though?
    , quoteDec = error "percentage is not supported at top-level"
    , quoteType = error "percentage is not supported as a type"
    }
    where

    quoteExp' :: String -> Q Exp
    quoteExp' s = case (readMay s :: Maybe Scientific) >>= mkPercentage of
      Nothing -> fail $ "Invalid Percentage: " ++ s
      Just percentage -> [| percentage |]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions