How to follow type inferences in Haskell? - haskell

Couldn't really follow the type inferences below, where case 1 worked but case 2 failed, why?
ghci> :t sqrt . maximum . map (+1) -- case 1
(Floating c, Ord c) => [c] -> c
ghci> :t sqrt . maximum . map length -- case 2
Could not deduce (Floating Int) arising from a use of ‘sqrt’
from the context (Foldable t)
bound by the inferred type of it :: Foldable t => [t a] -> Int
#EDIT
On OOP , Num is ususally the lower bound for all its subtypes e.g. Int and Float. Hence, Int will be inferentially acceptable if Num is the qualified type, but not vice versa.
Besides, on C-like languages, the built-in number conversion can automatically fulfill the case from the lower precision to the higher e.g. from Int to Float.
In contrast, on Haskell with HM type system, Num is the class for all its instances e.g. Int and the subclasses e.g. Floating. The qualified types can be bi-inferred between the ancestor and the descendant e.g. from Num to Int, Floating or vice versa, but not between Int and Floating.
To remedy case 2, Int should firstly be adapted to Num by fromIntegral or exerting Data.List.genericLength to produce the Num - the inferentially qualified type for Floating that sqrtrequires.
Let's apply the aforementioned points to follow the type inferences below,
ghci> :t (+)
Num a => a -> a -> a
ghci> :t 1.1
Fractional a => a
ghci> :i Fractional
class Num a => Fractional a
instance Fractional Float
instance Fractional Double
ghci> :t 1
Num a => a
ghci> :t length [1]
Int
ghci> :i Int
instance Num Int
instance Real Int
instance Integral Int
ghci> :t 1.1 + 1 -- case 1
Fractional a => a
ghci> :t 1.1 + length [1] -- case 2
No instance for (Fractional Int) arising from the literal ‘1.1’

1 can be any type of number and + can work with any type of number. The same is true for maximum. Thus maximum . map (+1) is a function that can can take a list of any type of number and produce a number of the same type as its result. This includes both integral numbers and floating point numbers.
However length will specifically produce an Int. It can not produce any other type of number. So maximum . map length can take any list and produce a result of type Int, not of any other numeric type.
Now sqrt needs its argument to be a floating point number. So in the first case type inference figures out that you must provide a list of floating point numbers, so the result of maximum . map (+1) will be a floating point number that can be passed to sqrt.
However the second case simply can not work because Int is not a floating point type and maximum . map length can't produce anything other than an Int. So this causes an error.
You can use the fromIntegral function to convert the result of length to any numeric type to make the second code work.

Related

fromInteger is a cast?

I'm looking at this, as well as contemplating the whole issue of non-decimal literals, e.g., 1, being just sugar for fromInteger 1 and then I find the type is
λ> :t 1
1 :: Num p => p
This and the statement
An integer literal represents the application of the function
fromInteger to the appropriate value of type Integer.
have me wondering what is really going on. Likewise,
λ> :t 3.149
3.149 :: Fractional p => p
Richard Bird says
A floating-point literal such as 3.149 represents the application of
fromRational to an appropriate rational number. Thus 3.149 :: Fractional a => a
Not understanding what the application of fromRational to an appropriate rational number means. Then he says this is all necessary to be able to add, e.g., 42 + 3.149.
I feel there's a lot going on here that I just don't understand. Like there's too much hand-waving for me. It seems like a cast of an unidentified non-decimal or decimal to specific types, Integer and Rational. So first, why is 1 actually fromInteger 1 internally? I realize every expression must be evaluated as a type, but why is fromInteger and fromRational involved?
Auxillary
So at this page
The workhorse for converting from integral types is fromIntegral,
which will convert from any Integral type into any Numeric type (which
includes Int, Integer, Rational, and Double): fromIntegral :: (Num b, Integral a) => a -> b
Then comes the example
λ> sqrt 1
1.0
λ> sqrt (1 :: Int)
... error...
λ> sqrt (fromInteger 1)
1.0
λ> :t sqrt 1
sqrt 1 :: Floating a => a
λ> :t sqrt (1 :: Int)
...error...
λ> :t sqrt
sqrt :: Floating a => a -> a
λ> :t sqrt (fromInteger 1)
sqrt (fromInteger 1) :: Floating a => a
So yes, this is a cast, but I don't know the mechanism of how fromI* is doing this --- since technically it's not a cast in a C/C++ sense. All instances of Num must have a fromInteger. It seems like under the hood Haskell is taking whatever you put in and generic-izing it to Integer or Rational, then "giving it back" to the original function, e.g., with sqrt (fromInteger 1) being of type Floating a => a. This is very mysterious to someone prone to over-thinking.
So yes, 1 is a literal, a constant that is polymorphic. It may represent 1 in any type that instantiates Num. The role of fromInteger must be to allowing a value (a cast) to be extracted from an integer constant consistent with what the situation calls for. But this is hand-waving talk at some point. I dont' get how this is actually happening.
Perhaps this will help...
Imagine a language, like Haskell, except that the literal program text 1 represents a term of type Integer with value one, and the literal program text 3.14 represents a term of type Rational with value 3.14. Let's call this language "AnnoyingHaskell".
To be clear, when I say "represents" in the above paragraph, I mean that the AnnoyingHaskell compiler actually compiles those literals into machine code that produces an Integer term whose value is the number 1 in the first case, and a Rational term whose value is the number 3.14 in the second case. An Integer is -- at it's core -- an arbitrary precision integer as implemented by the GMP library, while a Rational is a pair of two Integers, understood to be the numerator and denominator of a rational number. For this particular rational, the two integers would be 157 and 50 (i.e., 157/50=3.14).
AnnoyingHaskell would be... erm... annoying to use. For example, the following expression would not type check:
take 3 "hello"
because 3 is an Integer but take's first argument is an Int. Similarly, the expression:
42 + 3.149
would not type check, because 42 is an Integer and 3.149 is a Rational, and in AnnoyingHaskell, as in Haskell itself, you cannot add an Integer and a Rational.
Because this is annoying, the designers of Haskell made the decision that the literal program text 42 and 3.149 should be treated as if they were the AnnoyingHaskell expressions fromInteger 42 and fromRational 3.149.
The AnnoyingHaskell expression:
fromInteger 42 + fromRational 3.149
does type check. Specifically, the polymorphic function:
fromInteger :: (Num a) => Integer -> a
accepts the AnnoyingHaskell literal 42 :: Integer as its argument, and the resulting subexpression fromInteger 42 has resulting type Num a => a for some fresh type a. Similarly, fromRational 3.149 is of type Fractional b => b for some fresh type b. The + operator unifies these two types into a single type (Num c, Fractional c) => c, but Num c is redundant because Num is a superclass of Fractional, so the whole expression has a polymorphic type:
fromInteger 42 + fromRational 3.149 :: Fractional c => c
That is, this expression can be instantiated at any type with a Fractional constraint. For example. In the Haskell program:
main = print $ 42 + 3.149
which is equivalent to the AnnoyingHaskell program:
main = print $ fromInteger 42 + fromRational 3.149
the usual "defaulting" rules apply, and because the expression passed to the print statement is an unknown type c with a Fractional c constraint, it is defaulted to Double, allowing the program to actually run, computing and printing the desired Double.
If the compiler was awful, this program would run by creating a 42 :: Integer on the heap, calling fromInteger (specialized to fromInteger :: Integer -> Double) to create a 42 :: Double, then create 3.149 :: Rational on the heap, calling fromRational (specialized to fromRational :: Rational -> Double) to create a 3.149 :: Double, and then add them together to create the final answer 45.149 :: Double. Because the compiler isn't so awful, it just creates the number 45.149 :: Double directly.
Perhaps this will help more. One thing you seem to be struggling with is the nature of a value of type Num a => a, like the one produced by fromInteger (1 :: Integer). I think you're somehow imagining that fromInteger "packages" up the 1 :: Integer in a box so it can later be cast by special compiler magic to a 1 :: Int or 1 :: Double.
That's not what's happening.
Consider the following type class:
{-# LANGUAGE FlexibleInstances #-}
class Thing a where
thing :: a
with associated instances:
instance Thing Bool where thing = True
instance Thing Int where thing = 16
instance Thing String where thing = "hello, world"
instance Thing (Int -> String) where thing n = replicate n '*'
and observe the result of running:
main = do
print (thing :: Bool)
print (thing :: Int)
print (thing :: String)
print $ (thing :: Int -> String) 15
Hopefully, you're comfortable enough with type classes that you don't find the output surprising. And presumably you don't think that thing contains some specific, identifiable "thing" that is being "cast" to a Bool, Int, etc. It's simply that thing is a polymorphic value whose definition depends on its type; that's just how type classes work.
Now, consider the similar example:
{-# LANGUAGE FlexibleInstances #-}
import Data.Ratio
import Data.Word
import Unsafe.Coerce
class Three a where
three :: a
-- for base >= 4.10.0.0, can import GHC.Float (castWord64ToDouble)
-- more generally, we can use this unsafe coercion:
castWord64ToDouble :: Word64 -> Double
castWord64ToDouble w = unsafeCoerce w
instance Three Int where
three = length "aaa"
instance Three Double where
three = castWord64ToDouble 0x4008000000000000
instance Three Rational where
three = (6 :: Integer) % (2 :: Integer)
main = do
print (three :: Int)
print (three :: Double)
print (three :: Rational)
print $ take three "abcdef"
print $ (sqrt three :: Double)
Can you see here how three :: Three a => a represents a value that can be used as an Int, Double, or Rational? If you want to think of it as a cast, that's fine, but obviously there's no identifiable single "3" that's packaged up in the value three being cast to different types by compiler magic. It's just that a different definition of three is invoked, depending on the type demanded by the caller.
From here, it's not a big leap to:
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MagicHash #-}
import Data.Ratio
import Data.Word
import Unsafe.Coerce
class MyFromInteger a where
myFromInteger :: Integer -> a
instance MyFromInteger Integer where
myFromInteger x = x
instance MyFromInteger Int where
-- for base >= 4.10.0.0 can use the following:
-- -- Note: data Integer = IS Int | ...
-- myFromInteger (IS i) = I# i
-- myFromInteger _ = error "not supported"
-- to support more GHC versions, we'll just use this extremely
-- dangerous coercion:
myFromInteger i = unsafeCoerce i
instance MyFromInteger Rational where
myFromInteger x = x % (1 :: Integer)
main = do
print (myFromInteger 1 :: Integer)
print (myFromInteger 2 :: Int)
print (myFromInteger 3 :: Rational)
print $ take (myFromInteger 4) "abcdef"
Conceptually, the base library's fromInteger (1 :: Integer) :: Num a => a is no different than this code's myFromInteger (1 :: Integer) :: MyFromInteger a => a, except that the implementations are better and more types have instances.
See, it's not that the expression fromInteger (1 :: Integer) boxes up a 1 :: Integer into a package of type Num a => a for later casting. It's that the type context for this expression causes dispatch to an appropriate Num type class instance, and a different definition of fromInteger is invoked, depending on the required type. That fromInteger function is always called with argument 1 :: Integer, but the returned type depends on the context, and the code invoked by the fromInteger call (i.e., the definition of fromInteger used) to convert or "cast" the argument 1 :: Integer to a "one" value of the desired type depends on which return type is demanded.
And, to go a step further, as long as we take care of a technical detail by turning off the monomorphism restriction, we can write:
{-# LANGUAGE NoMonomorphismRestriction #-}
main = do
let two = myFromInteger 2
print (two :: Integer)
print (two :: Int)
print (two :: Rational)
This may look strange, but just as myFromInteger 2 is an expression of type Num a => a whose final value is produced using a definition of myFromInteger, depending on what type is ultimately demanded, the expression two is also an expression of type Num a => a whose final value is produced using a definition of myFromInteger that depends on what type is ultimately demanded, even though the literal program text myFromInteger does not appear in the expression two. Moreover, continuing with:
let four = two + two
print (four :: Integer)
print (four :: Int)
print (four :: Rational)
the expression four of type Num a => a will produce a final value that depends on the definition of myFromInteger and the definition of (+) that are determined by the finally demanded return type.
In other words, rather than thinking of four as a packaged 4 :: Integer that's going to be cast to various types, you need to think of four as completely equivalent to its full definition:
four = myFromInteger 2 + myFromInteger 2
with a final value that will be determined by using the definitions of myFromInteger and (+) that are appropriate for whatever type is demanded of four, whether its four :: Integer or four :: Rational.
The same goes for sqrt (fromIntegral 1) After:
x = sqrt (fromIntegral (1 :: Integer))
the value of x :: Floating a => a is equivalent to the full expression:
sqrt (fromIntegral (1 :: Integer))
and every place it is is used, it will be calculated using definitions of sqrt and fromIntegral determined by the Floating and Num instances for the final type demanded.
Here's all the code in one file, testing with GHC 8.2.2 and 9.2.4.
{-# LANGUAGE Haskell98 #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE NoMonomorphismRestriction #-}
import Data.Ratio
import GHC.Num
import GHC.Int
import GHC.Float (castWord64ToDouble)
class Thing a where
thing :: a
instance Thing Bool where thing = True
instance Thing Int where thing = 16
instance Thing String where thing = "hello, world"
instance Thing (Int -> String) where thing n = replicate n '*'
class Three a where
three :: a
instance Three Int where
three = length "aaa"
instance Three Double where
three = castWord64ToDouble 0x4008000000000000
instance Three Rational where
three = (6 :: Integer) % (2 :: Integer)
class MyFromInteger a where
myFromInteger :: Integer -> a
instance MyFromInteger Integer where
myFromInteger x = x
instance MyFromInteger Int where
-- Note: data Integer = IS Int | ...
myFromInteger (IS i) = I# i
myFromInteger _ = error "not supported"
instance MyFromInteger Rational where
myFromInteger x = x % (1 :: Integer)
main = do
print (thing :: Bool)
print (thing :: Int)
print (thing :: String)
print $ (thing :: Int -> String) 15
print (three :: Int)
print (three :: Double)
print (three :: Rational)
print $ take three "abcdef"
print $ (sqrt three :: Double)
print (myFromInteger 1 :: Integer)
print (myFromInteger 2 :: Int)
print (myFromInteger 3 :: Rational)
print $ take (myFromInteger 4) "abcdef"
let two = myFromInteger 2
print (two :: Integer)
print (two :: Int)
print (two :: Rational)
let four = two + two
print (four :: Integer)
print (four :: Int)
print (four :: Rational)

What does has kind 'Constraint' mean in Haskell

I am fresh to Haskell and I am trying to understand the language by writing some code. I am only familiar with very simple instructions on ghci: head, tail, sum, (*), and the like – very simple.
The function I am trying to make is for solving Pythagoras's theorem for vectors of any number of dimensions. This looks something like this: square root (a^2 + b^2 + c^2 ...)
What I can do in ghci in a few lines, which I am trying to make a function is the following:
sq x = x*x
b = map sq [1,2,3]
a = sum b
x = sqrt b
When I do this I try to include a signature of many sorts,
Currently my function looks like this:
mod :: [Num a] => a
mod x = sqrt a
where a = sum [b]
where [b] = map sq [x]
I do not understand the issue when I try to run it:
Expected a constraint, but ‘[Num a]’ has kind ‘*’
• In the type signature:
Main.mod :: [Num a] => a
A few things to adjust:
0) mod isn't a good name for your function, as it is the name of the modulo function from the standard library. I will call it norm instead.
1) The type signature you meant to write is:
norm :: Num a => [a] -> a
[a] is the type of a list with elements of type a. The Num a before the => isn't a type, but a constraint, which specifies that a must be a number type (or, more accurately, that it has to be an instance of the Num class). [Num a] => leads to the error you have seen because, given the square brackets, the type checker takes it as an attempt to use a list type instead of a constraint.
Beyond the Num a issue, you have left out the result type from the signature. The corrected signature reflects that your function takes a list of numbers and returns a number.
2) The Num a constraint is too weak for what you are trying to do. In order to use sqrt, you need to have not merely a number type, but one that is an instance of Floating (cf. leftaroundabout's comment to this answer):
GHCi> :t sqrt
sqrt :: Floating a => a -> a
Therefore, your signature should be
norm :: Floating a => [a] -> a
3) [x] is a list with a single element, x. If your argument is already a list, as the type signature says, there is no need to enclose it in square brackets. Your function, then, becomes:
norm :: Floating a => [a] -> a
norm x = sqrt a
where a = sum b
where b = map sq x
Or, more neatly, without the second where-block:
norm :: Floating a => [a] -> a
norm x = sqrt (sum b)
where b = map sq x
As you are aware, values can be classified by their type. "foo" has type [Char], Just 'c' has type Maybe Char, etc.
Similarly, types can be classified by their kind. All concrete types for which you can provide a value have kind *. You can see this using the :k command in GHCi:
> :k Int
Int :: *
> :k Maybe Int
Maybe Int :: *
Type constructors also have kinds. They are essentially type-valued functions, so their kinds are similar to regular functions.
> :t id
id :: a -> a
> :k Maybe
Maybe :: * -> *
But what is Num a? It's not a type, so it doesn't have kind *. It's not a type constructor, so it doesn't have an arrow kind. It is something new, so a new kind was created to describe it.
> :k Num Int
Num Int :: Constraint
And Num itself is a Constraint-valued function: it takes a value of kind * and produces a Constraint:
> :k Num
Num :: * -> Constraint
A thing with kind Constraint is used to specify the typeclass that a particular type must be an instance of. It is the value that can occur before => in a type signature. It is also the "argument" to the instance "function":
instance Num Int where
...

why is this snippet valid with an explicit value, but invalid as a function?

I'm trying to work a problem where I need to calculate the "small" divisors of an integer. I'm just bruteforcing through all numbers up to the square root of the given number, so to get the divisors of 10 I'd write:
[k|k<-[1...floor(sqrt 10)],rem 10 k<1]
This seems to work well. But as soon as I plug this in a function
f n=[k|k<-[1...floor(sqrt n)],rem n k<1]
And actually call this function, I do get an error
f 10
No instance for (Floating t0) arising from a use of `it'
The type variable `t0' is ambiguous
Note: there are several potential instances:
instance Floating Double -- Defined in `GHC.Float'
instance Floating Float -- Defined in `GHC.Float'
In the first argument of `print', namely `it'
In a stmt of an interactive GHCi command: print it
As far as I undrestand the actual print function that prints the result to the console is causing trouble, but I cannot find out what is wrong. It says the type is ambiguous, but the function can clearly only return a list of integers. Then again I checked the type, and it the (inferred) type of f is
f :: (Floating t, Integral t, RealFrac t) => t -> [t]
I can understand that fshould be able to accept any real numerical value, but can anyone explain why the return type should be anything else than Integral or int?
[k|k<-[1...floor(sqrt 10)],rem 10 k<1]
this works because the first 10 is not the same as the latter one - to see this, we need the type signature of your functions:
sqrt :: Floating a => a -> a
rem :: Integral a => a -> a -> a
so the first one means that it works for stuff that have a floating point representation - a.k.a. Float, Double ..., and the second one works for Int, Integer (bigint), Word8 (unsigned 8bit integers)...
so for the 10 in sqrt 10 the compiler says - ahh this is a floating point number, null problemo, and for the 10 in rem 10 k, ahh this is an integer like number, null problemo as well.
But when you bundle them up in a function - you are saying n has to be a floating point and an integral number, the compiler knows no such thing and - complains.
So what do we do to fix that (and a side note ranges in haskell are indicated by .. not ...!). So let us start by taking a concrete solution and generalize it.
f :: Int -> [Int]
f n = [k|k <- [1..n'],rem n k < 1]
where n' = floor $ sqrt $ fromIntegral n
the neccessary part was converting the Int to a floating point number. But if you are putting that in a library all your users need to stick with using Int which is okay, but far from ideal - so how do we generalize (as promised)? We use GHCi to do that for us, using a lazy language we ourselves tend to be lazy as well.
We start by commenting out the type-signature
-- f :: Int -> [Int]
f n = [k|k <- [1..n'],rem n k < 1]
where n' = floor $ sqrt $ fromIntegral n
$> ghci MyLib.hs
....
MyLib > :type f
f :: Integral a => a -> [a]
then we can take this and put it into the library and if someone worked with Word8 or Integer that would work as well.
Another solution would be to use rem (floor n) k < 1 and have
f :: Floating a, Integral b => a -> [b]
as the type, but that would be kind of awkward.

I don't understand number conversions in Haskell

Here is what I'm trying to do:
isPrime :: Int -> Bool
isPrime x = all (\y -> x `mod` y /= 0) [3, 5..floor(sqrt x)]
(I know I'm not checking for division by two--please ignore that.)
Here's what I get:
No instance for (Floating Int)
arising from a use of `sqrt'
Possible fix: add an instance declaration for (Floating Int)
In the first argument of `floor', namely `(sqrt x)'
In the expression: floor (sqrt x)
In the second argument of `all', namely `[3, 5 .. floor (sqrt x)]'
I've spent literally hours trying everything I can think of to make this list using some variant of sqrt, including nonsense like
intSqrt :: Int -> Int
intSqrt x = floor (sqrt (x + 0.0))
It seems that (sqrt 500) works fine but (sqrt x) insists on x being a Floating (why?), and there is no function I can find to convert an Int to a real (why?).
I don't want a method to test primality, I want to understand how to fix this. Why is this so hard?
Unlike most other languages, Haskell distinguishes strictly between integral and floating-point types, and will not convert one to the other implicitly. See here for how to do the conversion explicitly. There's even a sqrt example :-)
The underlying reason for this is that the combination of implicit conversions and Haskel's (rather complex but very cool) class system would make type reconstruction very difficult -- probably it would stretch it beyond the point where it can be done by machines at all. The language designers felt that getting type classes for arithmetic was worth the cost of having to specify conversions explicitly.
Your issue is that, although you've tried to fix it in a variety of ways, you haven't tried to do something x, which is exactly where your problem lies. Let's look at the type of sqrt:
Prelude> :t sqrt
sqrt :: (Floating a) => a -> a
On the other hand, x is an Int, and if we ask GHCi for information about Floating, it tells us:
Prelude> :info Floating
class (Fractional a) => Floating a where
pi :: a
<...snip...>
acosh :: a -> a
-- Defined in GHC.Float
instance Floating Float -- Defined in GHC.Float
instance Floating Double -- Defined in GHC.Float
So the only types which are Floating are Floats and Doubles. We need a way to convert an Int to a Double, much as floor :: (RealFrac a, Integral b) => a -> b goes the other direction. Whenever you have a type question like this, you can ask Hoogle, a Haskell search engine which searches types. Unfortunately, if you search for Int -> Double, you get lousy results. But what if we relax what we're looking for? If we search for Integer -> Double, we find that there's a function fromInteger :: Num a => Integer -> a, which is almost exactly what you want. And if we relax our type all the way to (Integral a, Num b) => a -> b, you find that there is a function fromIntegral :: (Integral a, Num b) => a -> b.
Thus, to compute the square root of an integer, use floor . sqrt $ fromIntegral x, or use
isqrt :: Integral i => i -> i
isqrt = floor . sqrt . fromIntegral
You were thinking about the problem in the right direction for the output of sqrt; it returned a floating-point number, but you wanted an integer. In Haskell, however, there's no notion of subtyping or implicit casts, so you need to alter the input to sqrt as well.
To address some of your other concerns:
intSqrt :: Int -> Int
intSqrt x = floor (sqrt (x + 0.0))
You call this "nonsense", so it's clear you don't expect it to work, but why doesn't it? Well, the problem is that (+) has type Num a => a -> a -> a—you can only add two things of the same type. This is generally good, since it means you can't add a complex number to a 5×5 real matrix; however, since 0.0 must be an instance of Fractional, you won't be able to add it to x :: Int.
It seems that (sqrt 500) works fine…
This works because the type of 500 isn't what you expect. Let's ask our trusty companion GHCi:
Prelude> :t 500
500 :: (Num t) => t
In fact, all integer literals have this type; they can be any sort of number, which works because the Num class contains the function fromInteger :: Integer -> a. So when you wrote sqrt 500, GHC realized that 500 needed to satisfy 500 :: (Num t, Floating t) => t (and it will implicitly pick Double for numeric types like that thank to the defaulting rules). Similarly, the 0.0 above has type Fractional t => t, thanks to Fractional's fromRational :: Rational -> a function.
… but (sqrt x) insists on x being a Floating …
See above, where we look at the type of sqrt.
… and there is no function I can find to convert an Int to a real ….
Well, you have one now: fromIntegral. I don't know why you couldn't find it; apparently Hoogle gives much worse results than I was expecting, thanks to the generic type of the function.
Why is this so hard?
I hope it isn't anymore, now that you have fromIntegral.

Is it square check

I am trying to write function to check if the argument is square of integer:
isSquare :: Int -> Bool
isSquare x = truncate(sqrt(x)) * truncate(sqrt(x)) == x
When I loading the function I get the error:
Prelude> :load "some.hs"
[1 of 1] Compiling Main ( some.hs, interpreted )
some.hs:2:13:
No instance for (RealFrac Int)
arising from a use of `truncate' at some.hs:2:13-29
Possible fix: add an instance declaration for (RealFrac Int)
In the first argument of `(*)', namely `truncate (sqrt (x))'
In the first argument of `(==)', namely
`truncate (sqrt (x)) * truncate (sqrt (x))'
In the expression: truncate (sqrt (x)) * truncate (sqrt (x)) == x
some.hs:2:22:
No instance for (Floating Int)
arising from a use of `sqrt' at some.hs:2:22-28
Possible fix: add an instance declaration for (Floating Int)
In the first argument of `truncate', namely `(sqrt (x))'
In the first argument of `(*)', namely `truncate (sqrt (x))'
In the first argument of `(==)', namely
`truncate (sqrt (x)) * truncate (sqrt (x))'
Failed, modules loaded: none.
But if i try to execute:
Prelude> truncate(sqrt(9))*truncate(sqrt(9))==9
True
all is fine.
Why I get the error and how to fix it ?
You're getting the errors because of type mismatches. The type of sqrt is sqrt :: Floating a => a -> a, and the type of truncate is truncate :: (RealFrac a, Integral b) => a -> b. The former says that sqrt takes as input any floating-point number, and returns one of the same type as output; the latter says it can truncate any real fractional number1 into any integral number. However, you assert that x is an Int, and an Int isn't a floating-point number. Thus, the second error: "No instance for (Floating Int) arising from a use of `sqrt'". This says that because of sqrt x, it wanted Int to be a floating-point number, but there's no definition for that. Your first error is similar: since sqrt :: Floating a => a -> a, its output is the same as its input, so you're trying to call truncate on an integer. This of course makes no sense, since Int is not a RealFrac, and that's why you get the first error. Fixing this is easy:
isSquare :: Int -> Bool
isSquare x = let x' = truncate $ sqrt (fromIntegral x :: Double) in x'*x' == x
The fromIntegral function has the type fromIntegral :: (Integral a, Num b) => a -> b; it can convert any integral number into any number at all. This is why we need to tell Haskell that we want it to produce a Double; it'd default to that anyway, but it's nice to be clear (though not necessary). Double is an instance both of Floating and RealFrac, so you can sqrt and truncate it. I also rearranged your code a little; the way it is up there is how I'd write it, since this way we only compute the truncation and sqrt once. Also, note that if you remove the type signature, Haskell will infer the more general type isSquare :: Integral a => a -> Bool, since you never assume that x is precisely an Int.
The reason that truncate(sqrt(9))*truncate(sqrt(9))==9 successfully returned True is because of the type of 9. You can ask GHCi to tell you this:
Prelude> :t 9
9 :: (Num t) => t
In Haskell, all integral numeric literals have the type Num t => t (9.0, or any number with a decimal point, has the type Fractional t => t). This means that they can be any kind of number at all, which is a good thing. Otherwise, 9 would have to just be an Int or Integer, and defining new number types—or even using both Int and Integer!2—would be a royal pain. Thus, when you write truncate(sqrt(9)), GHCi determines that 9 must be an instance of Floating (from sqrt) and RealFrac (from truncate), which it defaults to Double, making everything work. This defaulting is standard behavior for numeric types (it's why you could leave out the :: Double in my definition of isSquare), though not for anything else (except in GHCi, which extends it for convenience). Since 9 isn't just an Int, but x is, you don't need to convert 9, but you do need to convert x.
1: The difference between Floating and RealFrac is that, for instance, Complex Double is an instance of Floating but not RealFrac, and Rational is an instance of RealFrac but not Floating. Float and Double are instances of both.
2: In case you haven't come across this, the difference is that Int is finite-precision, and Integer is arbitrary-precision.
You're treating integers as floats. Hence, the types don't match.
Use fromIntegral:
isSquare :: Int -> Bool
isSquare n = truncate(sqrt(x)) * truncate(sqrt(x)) == n
where x = fromIntegral n
Not all that efficient but a cute way of determining if a number is a square, using integer arithmetic only:
isSquare x = x == head (dropWhile (< x) squares)
where squares = scanl1 (+) [1,3..]

Resources