Arnon
Arnon

Reputation: 2237

Defaulting the following constraints to type 'Double' when using Scientific

I have two scientific numbers that are necessarily Integers that I want to convert to Ints, as below.

Please ignore code conventions and the idiomaticness of the code.

> import qualified Data.Vector as V
> import Data.Scientific

> cToTy (Array v) = case V.toList v of
>     [String nm, Number p, Number s] 
>      | all (==True) $ map isInteger [p,s]  -- We make sure they're always integers
>      , [pr,sc] <- map (forceEitherToInt . floatingOrInteger) [p,s] -- And then hack them out

> forceEitherToInt :: (RealFloat r, Integral i) => Either r i -> Int
> forceEitherToInt (Left _a) = 0 -- This shouldn't happen, so we'll default it to 0 all the time.
> forceEitherToInt (Right a) = fromIntegral a

However, I get this warning and I can't figure out how to rid myself of them.

JsonUtils.lhs:76:26: Warning:
    Defaulting the following constraint(s) to type ‘Double’
      (RealFloat r0) arising from a use of ‘forceEitherToInt’
    In the first argument of ‘(.)’, namely ‘forceEitherToInt’
    In the first argument of ‘map’, namely
      ‘(forceEitherToInt . floatingOrInteger)’
    In a stmt of a pattern guard for
                   a case alternative:
      [pr, sc] <- map (forceEitherToInt . floatingOrInteger) [p, s]

Does anyone have any thoughts or ideas?

Upvotes: 2

Views: 1617

Answers (1)

CR Drost
CR Drost

Reputation: 9817

First off, you can explicitly cause an error if "neither should happen"; second, you can drop RealFloat as @bheklilr states; thirdly you can specify the double more concretely if you prefer the double; fourthly it can help with Hungarian notation if you write 'A from B' rather than 'B to A' in your names. So you could write for example:

intFromEither :: (Integral i) => Either Double i -> Int
intFromEither (Left d) = error $ 
    "intFromEither tried to coerce `Left " ++ show d ++ "` to an Int."
intFromEither (Right i) = fromIntegral i

You can replace the Double above with x to make it more general; the most general type signature here is (Integral a, Num b) => Either t a -> b.

Upvotes: 3

Related Questions