I'm have the following code in the file main.hs:
teste :: Integral a => a -> a
teste n = truncate (sqrt n) + mod n 2
and i'm getting the following error from ghci when I try to load it:
Prelude> :l main.hs
[1 of 1] Compiling Main ( main.hs, interpreted )
main.hs:12:11:
Could not deduce (RealFrac a) arising from a use of ‘truncate’
from the context (Integral a)
bound by the type signature for teste :: Integral a => a -> a
at main.hs:11:10-29
Possible fix:
add (RealFrac a) to the context of
the type signature for teste :: Integral a => a -> a
In the first argument of ‘(+)’, namely ‘truncate (sqrt n)’
In the expression: truncate (sqrt n) + mod n 2
In an equation for ‘teste’: teste n = truncate (sqrt n) + mod n 2
main.hs:12:21:
Could not deduce (Floating a) arising from a use of ‘sqrt’
from the context (Integral a)
bound by the type signature for teste :: Integral a => a -> a
at main.hs:11:10-29
Possible fix:
add (Floating a) to the context of
the type signature for teste :: Integral a => a -> a
In the first argument of ‘truncate’, namely ‘(sqrt n)’
In the first argument of ‘(+)’, namely ‘truncate (sqrt n)’
In the expression: truncate (sqrt n) + mod n 2
Failed, modules loaded: none.
but when I run the same code in the interective mode, it works fine:
Prelude> truncate (sqrt 5) + mod 5 2
3
And since Haskell is not object-oriented, there is no inheritance relationship that required any cast. There simply aren't meaningless object values that needed runtime-checking/casting. For expressing alternatives, you'll have to define a union type, a typeclass or use the Either type.
The workhorse for converting from integral types is fromIntegral , which will convert from any Integral type into any Num eric type (which includes Int , Integer , Rational , and Double ): fromIntegral :: (Num b, Integral a) => a -> b.
In Haskell, we can convert Int to Float using the function fromIntegral .
What's the difference between Integer and Int ? Integer can represent arbitrarily large integers, up to using all of the storage on your machine. Int can only represent integers in a finite range.
In your call truncate (sqrt 5) + mod 5 2
, the 5
s have different types. Indeed the 5
in the sqrt 5
should have as type Floating a => a
, whereas the 5
in mod 5 2
has type Integral b => b
. Although it is, strictly speaking possible to construct a type in Haskell that is a member of both type families, conceptually it is odd that a type is both Integral
and Floating
, it would also only be applicable to such types, making it less useful. We thus could change the signature to:
teste :: (Integral a, Floating a, RealFrac a) => a -> a
teste n = truncate (sqrt n) + mod n 2
but as said before, this is not very useful.
You can use fromIntegral :: (Integral a, Num b) => a -> b
here to convert from an Integral
type to any Num
type, like:
teste :: Integral a => a -> a
teste n = truncate (sqrt (fromIntegral n)) + mod n 2
For example:
Prelude> teste 5
3
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With