Unintuitive type signature in Haskell - haskell

I made this (what I thought to be) fairly straightforward code to calculate the third side of a triangle:
toRadians :: Int -> Double
toRadians d = let deg = mod d 360
in deg/180 * pi
lawOfCosines :: Int -> Int -> Int -> Double
lawOfCosines a b gamma = sqrt $ a*a + b*b - 2*a*b*(cos (toRadians gamma))
However, when I tried to load it into GHCi, I got the following errors:
[1 of 1] Compiling Main ( law_of_cosines.hs, interpreted )
law_of_cosines.hs:3:18:
Couldn't match expected type `Double' with actual type `Int'
In the first argument of `(/)', namely `deg'
In the first argument of `(*)', namely `deg / 180'
In the expression: deg / 180 * pi
law_of_cosines.hs:6:26:
No instance for (Floating Int)
arising from a use of `sqrt'
Possible fix: add an instance declaration for (Floating Int)
In the expression: sqrt
In the expression:
sqrt $ a * a + b * b - 2 * a * b * (cos (toRadians gamma))
In an equation for `lawOfCosines':
lawOfCosines a b gamma
= sqrt $ a * a + b * b - 2 * a * b * (cos (toRadians gamma))
law_of_cosines.hs:6:57:
Couldn't match expected type `Int' with actual type `Double'
In the return type of a call of `toRadians'
In the first argument of `cos', namely `(toRadians gamma)'
In the second argument of `(*)', namely `(cos (toRadians gamma))'
It turns out the fix was to remove my type signatures, upon which it worked fine.
toRadians d = let deg = mod d 360
in deg/180 * pi
lawOfCosines a b gamma = sqrt $ a*a + b*b - 2*a*b*(cos (toRadians gamma))
And when I query the type of toRadians and lawOfCosines:
*Main> :t toRadians
toRadians :: (Floating a, Integral a) => a -> a
*Main> :t lawOfCosines
lawOfCosines :: (Floating a, Integral a) => a -> a -> a -> a
*Main>
Can someone explain to me what's going on here? Why the "intuitive" type signatures I had written were in fact incorrect?

The problem is in toRadians: mod has the type Integral a => a -> a -> a, therefore, deg has the type Integral i => i (so either Int or Integer).
You then try and use / on deg, but / doesn't take integral numbers (divide integrals with div):
(/) :: Fractional a => a -> a -> a
The solution is to simply use fromIntegral :: (Integral a, Num b) => a -> b:
toRadians :: Int -> Double
toRadians d = let deg = mod d 360
in (fromIntegral deg)/180 * pi

Seeing Floating a and Integral a in a type signature together always sets off my internal alarm bells, as these classes are supposed to be mutually exclusive - at least, there are no standard numeric types that are instances of both classes. GHCi tells me (along with a lot of other stuff):
> :info Integral
...
instance Integral Integer -- Defined in `GHC.Real'
instance Integral Int -- Defined in `GHC.Real'
> :info Floating
...
instance Floating Float -- Defined in `GHC.Float'
instance Floating Double -- Defined in `GHC.Float'
To see why these classes are mutually exclusive, let's have a look at some of the methods in both classes (this is going to be a bit handwavy). fromInteger in Integral converts an Integral number to an Integer, without loss of precision. In a way, Integral captures the essence of being (a subset of) the mathematical integers.
On the other hand, Floating contains methods such as pi and exp, which have a pronounced 'real number' flavour.
If there were a type that was both Floating and Integral, you could write toInteger pi and have a integer that was equal to 3.14159... - and that's not possible :-)
That said, you should change all your type signatures to use Double instead of Int; after all, not all triangles have integer sides, or angles that are an integral number of degrees!
If you absolutely don't want that for whatever reason, you also need to convert the sides (the a and b arguments) in lawOfCosines to Double. That's possible via
lawOfCosines aInt bInt gamma = sqrt $ a*a + b*b - 2*a*b*(cos (toRadians gamma)) where
a = fromInteger aInt
b = fromInteger bInt

The type signature for toRadians says it takes an Int but returns a Double. In some programming languages, the conversion from one to the other (but not back) happens automatically. Haskell is not such a language; you must manually request conversion, using fromIntegral.
The errors you are seeing are all coming from various operations which don't work on Int, or from trying to add Int to Double, or similar. (E.g., / doesn't work for Int, pi doesn't work for Int, sqrt doesn't work for Int...)

Related

Overloading operators :: HaskellNewbie

I'm making a new type so I can calculate big numbers with some precision. Basically its a Double and a Integer to represent a number as Double * 10 ^ Integer. Now I began to make the program and it was going "ok" till I tried to make a instance of my new number so I could simple use + to add my new numbers up. This makes it easier for me to use in my existing programs. But I'm just getting a errors along the lines of "Could not deduce" from my code (I'll post an example below). I somewhat understand the error, but I can seem to get around the problem. If you wish to compile the code, comment lines 4 and 5.
I'v been working on this for hours and is "killing" me.
newtype Sci f p = Sci (f ,p) deriving (Eq,Show)
instance (Floating a,Integral b) => Num (Sci a b) where
Sci (a,b) * Sci (c,d) = fixSci( Sci(a*c,b*d) )
mulSci :: Sci Double Integer -> Sci Double Integer -> Sci Double Integer
mulSci (Sci(a,b)) (Sci(c,d)) = fixSci (Sci(a*c,b*d))
mkSci :: Double -> Sci Double Integer
mkSci 0 = Sci(0, 0)
mkSci n = let lg = (floor ((log10 . abs) n)) in Sci((n/(10**(fromIntegral lg))), if lg > 0 then lg else 0)
fixSci :: Sci Double Integer -> Sci Double Integer
fixSci (Sci(a,b)) = let n = mkSci a in (\(Sci(c,d)) -> Sci(c,b+d)) n
fromSci (Sci(a,b)) = a*10**(fromIntegral b)
showSci (Sci(a,b)) = (show a)++"e"++(show b)
lx :: Double
lx = log 10
log10 :: Double -> Double
log10 y = log y / lx
-- ~ main = putStrLn $ showSci $ fixSci $ Sci(95,0)
main = putStrLn $ showSci $ mkSci 95
Here is an example error:
sci.hs:5:40:
Could not deduce (a ~ Double)
from the context (Floating a, Integral b)
bound by the instance declaration at sci.hs:4:10-49
`a' is a rigid type variable bound by
the instance declaration at sci.hs:4:20
In the first argument of `(*)', namely `a'
In the expression: a * c
In the first argument of `Sci', namely `(a * c, b * d)'
sci.hs:5:44:
Could not deduce (b ~ Integer)
from the context (Floating a, Integral b)
bound by the instance declaration at sci.hs:4:10-49
`b' is a rigid type variable bound by
the instance declaration at sci.hs:4:31
In the first argument of `(*)', namely `b'
In the expression: b * d
In the first argument of `Sci', namely `(a * c, b * d)'
Any help is much appreciated!
Admittedly, reading and understanding GHC error messages is not easy. Therefore, your question is valid.
Obviously, the messages are referring to your definition of the * operator. We can tell this from the line number mentioned in sci.hs:5:40 and from the fact that (*) is the only one you defined in your Num instance.
Remember the general type of *, it is
(*) :: Num n => n -> n -> n
which means: For all types n that have a Num instance, if you give 2 values of that type to *, you will get back another value of same type. Or simpler: (*) will work for any numeric type, as long as the factors are of the same type and the result will have the same type as the factors.
Needless to say, your implementation of * must fulfill this contract. And because your Sci type itself is polymorphic, your incarnation has the type:
(*) :: (Floating a, Integral b) => Sci a b -> Sci a b -> Sci a b
So your are claiming that your multiplication will work for type Sci a b for any types a and b, as long as a is a Floating type and b is an Intergal type. That is, it should work for Sci Float Int as well as for Sci Double Integer.
By now, you should already know what the error is: Your implementation doesn't live up to that promise. In fact, it only works for Sci Double Integer, because your helper function fixSci can only work with Sci Double Integer.
The error message tries to tell you just that, in a more technical form. It lists
the type conflict a vs Double ("You promised to give me anything, but all I got was a lousy Double!")
the constraints actually in scope ("You said, a was an instance of Floating) and where it was introduced.
The expression(s) that led the compiler to infer Double
Unfortunately, the compiler stops short (for brevity, as it is known that newbies never read error messages anyway :) before the interesting part. It could have included something like
in the expression fixSci (Sci (a*c) (b*d)),
and since fixSci takes an argument of type Sci Double Integer
I concluded that Sci (a*c) (b*d) must be Sci Double Integer
and hence (a*c) must be Double.
Not really related to your question, but to your code:
Should it really be mulSci (Sci(a,b)) (Sci(c,d)) = fixSci (Sci(a*c,b*d))?
Shouldn't it be b+d instead of b*d?
Why don't you just set newtype Sci = Sci Double Integer?
Then you would have
instance Num Sci where
(Sci m1 e1) * (Sci m2 e2) = fixSci (Sci (m1*m2) (e1+e2))
(Sci m1 e1) + (Sci m2 e2) = <some rather complicated expression>
Not your original question, but your showSci function bothers me:
Don't derive Show, write your own show function:
instance Show Sci where
show (Sci (a,b)) = (show a) ++ "e" ++ (show b)
Then main becomes:
main = print $ mkSci 95

Finding norm of vector using hmatrix in haskell

I just started learning Haskell and am having trouble with
using the hmatrix library. I want to write some simple code
to compute the eigenvalue using the power iteration method.
I start with:
c = fromList [4.0, 4.0, 4.0, 4.0]::Vector Double
n = norm2 c
Which creates a vector c and finds the 2-norm of the vector.
Multiplication with c:
c * 2 (Works)
c * 0.5 (Works)
c * pi (Works)
c * n (Error)
I checked that:
>:t pi
pi :: Floating a => a
>:t n
n :: Double
The problem is with the types but I do not know how to get
around it.
Would I need to define my own (/) function in this case?
Update:
The error I obtain from ghci:
Couldn't match expected type `Vector Double'
with actual type `Double'
In the second argument of `(*)', namely `n'
In the expression: c * n
In an equation for `it': it = c * n
You're doing the right thing by checking the types. If we're a bit more explicit, we can see what is going on.
Prelude Numeric.LinearAlgebra> :t let a = 2; b = c * a in a
let a = 2; b = c * a in a :: Vector Double
The problem is that the type of norm2 c is Double and thus cannot be made into a Vector Double
Let's see the value of that polymorphic 2 from earlier.
Prelude Numeric.LinearAlgebra> let a = 2; b = c * a in a
fromList [2.0]
So instead, n = fromList [norm2 c]
Edit: The very same library exposes functions scalar and scale which you should look into.
(*) assumes that both of its arguments have the same type:
(*) :: (Num a) => a -> a -> a
The reason that your first three multiplications worked was because in all three cases the right argument successfully type-checked as a Vector Double!
To see why, let's ask ghci what the types of those three arguments are:
> :t 2
2 :: Num a => a
> :t 0.5
0.5 :: Fractional a => a
> :t pi
pi :: Floating a => a
All three of those are valid Vector Doubles because hmatrix provides the following three instances:
instance Num (Vector Double) where ...
instance Fractional (Vector Double) where ...
instance Floating (Vector Double) where ...
In other words, Haskell will transform 2, 0.5, and pi into Vector Doubles automatically, thanks to those instances.
This explains why your last example does not type check. n has type Double, which means that there is no chance it can ever type-check also as a Vector Double.

Haskell, multiplying Int and Float within a function

Why is it that in ghci I can enter:
5.0 * (3 - 1)
> 10.0
But if I try and create a function in a .hs file and load it in:
test :: Float -> Int -> Int -> Float
test a b c = a * (b - c)
I am hit with an error? "Couldnt match expected type 'Float' against inferred type 'Int'?
And how can I write a function that takes in one floating point and 2 integer arguments and performs the above operation on them?
I am using ghci v6.12.1 if that makes a difference...
Numeric literals (i.e. just typing a number in Haskell code) are not some fixed type. They are polymorphic. They need to be evaluated in some context that requires them to have a concrete type.
So the expression 5.0 * (3 - 1) is not multiplying an Int by a Float. 5.0 has to be some Fractional type, 3 and 1 are each some Num type. 3 - 1 means that the 3 and the 1 both have to be the same Num type, but we still don't (yet) have any more constraints about which particular one it is; the result of the subtraction is the same type.
The * means both arguments have to be the same type, and the result will be the same type too. Since 5.0 is some Fractional type, the (3 - 1) must be too. We already knew that 3, 1, and (3 - 1) had to be some Num type but all Fractional types are also Num types, so this requirements are not in conflict.
The end result is that the whole expression 5.0 * (3 - 1) is some type that is Fractional, and the 5.0, 3, and 1 are all the same type. You can use the :t command in GHCi to see this:
Prelude> :t 5.0 * (3 - 1)
5.0 * (3 - 1) :: Fractional a => a
But to actually evaluate that expression, we need to do so for some concrete type. If we were evaluating this and passing it to some function that required Float, Double, or some other particular Fractional type then Haskell would pick that one. If we just evaluate the expression with no other context requiring it to be a particular type, Haskell has some defaulting rules to automatically choose one for you (if the defaulting rules don't apply it will instead give you a type error about ambiguous type variables).
Prelude> 5.0 * (3 - 1)
10.0
Prelude> :t it
it :: Double
Above I've evaluated 5.0 * (3 - 1), then asked for the type of the magic it variable which GHCi always binds to the last value it evaluated. This tells me that GHCi has defaulted my Fractional a => a type to just Double, in order to compute that the value of the expression was 10.0. In doing that evaluation, it only ever multipled (and subtracted) Doubles, it never multiplied a Double by an Int.
Now, that's what's going on when you attempt to multiple numeric literals that look like they might be of different types. But your test function isn't multiplying literals, it's multiplying variables of particular known types. In Haskell you can't multiply an Int by a Float because the * operator has type Num a => a -> a -> a - it takes two values of the same numeric type and gives you a result that is that type. You can multiply an Int by an Int to get an Int, or a Float by a Float to get a Float. You can't multiply an Int by a Float to get a ???.
Other languages support this sort of operation only by implicitly inserting calls to conversion functions under some circumstances. Haskell never implicitly converts between types, but it has the conversion functions. You just need to call them explicitly if you want them to be called. This would do the trick:
test :: Float -> Int -> Int -> Float
test a b c = a * fromIntegral (b - c)
Try the following instead:
test :: Float -> Int -> Int -> Float
test a b c = a * fromIntegral (b - c)
Why does this work?
Since b and c are both Ints the expression (b - c) is also an Int.
The type signature of (*) is Num a => a -> a -> a.
Because a is of type Float Haskell updates the type signature of (a*) to Float -> Float.
However since (b - c) is an Int and not a Float Haskell would complain if you tried doing a * (b - c).
The type signature of fromIntegral is (Integral a, Num b) => a -> b.
Hence the type signature of fromIntegral (b - c) is Num b => b.
Since Float is an instance of typeclass Num you're allowed to do a * fromIntegral (b - c) because the type signature of (*) is Num a => a -> a -> a.
The result, from the type signature of test evaluates to Float.
Hope this helped.
You need to use fromIntegral on the integers before multiplying by the floats.
http://www.haskell.org/haskellwiki/Converting_numbers
In GHCI, the numbers aren't assumed to be floats or ints until you use them. (e.g: at run time). That works out better for REPL-style development.
In the compiler proper, there isn't any automatic coercion. It it sees the multiplication assumes that the two values must belong to a type-class that supports multiplication. e.g: multiplying ints , or multiplying floats. As you didn't use any other explicitly typed functions, it assumed ints. That assumption then differs with your (optional) type signature.
Your test function was more general, before you add a signature:
> let test a b c = a * (b - c)
> :t test
test :: Num a => a -> a -> a -> a
You could restrict it, but all types must be the same:
test :: Fractional a => a -> a -> a -> a -- some real types
test :: Integral a => a -> a -> a -> a -- all integer types
test :: Float -> Float -> Float -> Float
test :: Int -> Int -> Int -> Int
test :: Int -> Float -> Float -> Float --wrong
By the way, 2 isn't Int and 0.2 isn't Float, let ask gchi:
> :t 2
2 :: Num a => a
> :t 0.2
0.2 :: Fractional a => a

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