Reputation: 2237
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
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