Couldn't match type 'b' with Int - haskell

Task: Transform a list of numbers using map so every even number gets divided by 2 and every odd number gets multiplied by 2
prel2 :: (Fractional b) => [Int] -> [b]
prel2 x = map prel x
where prel y
|even y = y/2
|otherwise = y*2
I know this is some basic stuff, but I can't figure out why the error is raised

Your type signature promises that you can provide a list of values of any type that has a Fractional instance. But, since y is always an Int (since x :: [Int]), then y*2 will always be an Int, and y/2 wouldn't type-check at all.
What you probably want is to use div instead of / to replace the Fractional constraint with an Integral constraint, then generalize your type to Integral b => [b] -> [b].

Related

Convert Num to Doublle in Haskell

I am trying to write a function that calculates the average of the values of a list containing type Num.
Here is what I tried:
mean :: Num a => [a] -> Double
mean [] = error "Trying to calculate mean of 0 values"
mean x = sumx / lengthx
where
sumx = fromIntegral (sum x)
lengthx = fromIntegral length x
GHCI rejects the fromIntegral function because it expects an Integral type not a Num.
Is there a way to convert a Num, whatever its specific type, to a Double?
The problem with converting Num a => a to a Double is that a Num may not actually be a number at all. There is no requirement for a member of the Num class to be a number of some sort. You can go and implement an instance of Num for anything, even for unit.
One obvious real-life example is Complex: it has an instance of Num, but a complex number can't always be converted to a real one.
If you want your function to work with integers, just specify Integral as your constraint.
OK, I finally found the way to do this:
mean :: Fractional a => [a] -> a
mean xs = sum xs / fromIntegral (length xs)
This works even if I apply it to a list of Integers. I am not sure why because Fractional does not apply to Integers according to the documentation I have read.
My understanding of Haskell is still obviously quite limited.
A more general way to write it is to use Real:
mean :: (Real a, Fractional b) => [a] -> b
mean xs = realToFrac (sum xs) / fromIntegral (length xs)
But that is not completely satisfactory because this doesn't work on lists of Complex numbers or other non-Real numbers.

Difference between -> and => symbols. What do they mean?

In Haskell, when we talk type declaration.
I've seen both -> and =>.
As an example: I can make my own type declaration.
addMe :: Int -> Int -> Int
addMe x y = x + y
And it works just fine.
But if we take a look at :t sqrt we get:
sqrt :: Floating a => a -> a
At what point do we use => and when do we use ->?
When do we use "fat arrow" and when do we use "thin arrow"?
-> is for explicit functions. I.e. when f is something that can be written in an expression of the form f x, the signature must have one of these arrows in it†. Specifically, the type of x (the argument) must appear to the left of a -> arrow.
It's best to not think of => as a function arrow at all, at least at first‡. It's an implication arrow in the logical sense: if a is a type with the property Floating a, then it follows that the signature of sqrt is a -> a.
For your addMe example, which is a function with two arguments, the signature must always have the form x -> y -> z. Possibly there can also be a q => in front of that; that doesn't influence the function-ishness, but may have some saying in what particular types are allowed. Generally, such constraints are not needed if the types are already fixed and concrete. Like, you could in principle impose a constraint on Int:
addMe :: Num Int => Int -> Int -> Int
addMe x y = x + y
...but that doesn't really accomplish anything, because everybody knows that the particular type Int is an instance of the Num class. Where you need such constraints is when the type is not fixed but a type variable (i.e. lowercase), i.e. if the function is polymorphic. You can't just write
addMe' :: a -> a -> a
addMe' x y = x + y
because that signature would suggest the function works for any type a whatsoever, but it can't work for all types (how would you add, for example, two strings? ok perhaps not the best example, but how would you multiply two strings?)
Hence you need the constraint
addMe' :: Num a => a -> a -> a
addMe' x y = x + y
This means, you don't care what exact type a is, but you do require it to be a numerical type. Anybody can use the function with their own type MyNumType, but they need to ensure that Num MyNumType is fulfilled: then it follows that addMe' can have signature MyNumType -> MyNumType -> MyNumType.
The way to ensure this is to either use a standard type which you know to be numerical, for instance addMe' 5.9 3.7 :: Double would work, or give an instance declaration for your custom type and the Num class. Only do the latter if you're sure it's a good idea; usually the standard num types are all you'll need.
†Note that the arrow may not be visible in the signature: it's possible to have a type synonym for a function type, for example when type IntEndofunc = Int -> Int, then f :: IntEndofunc; f x = x+x is ok. But you can think of the typedef as essentially just a syntactic wrapper; it's still the same type and does have the arrow in it.
‡It so happens that logical implication and function application can be seen as two aspects of the same mathematical concept. Furthermore, GHC actually implements class constraints as function arguments, so-called dictionaries. But all this happens behind the scenes, so if anything they're implicit functions. In standard Haskell, you will never see the LHS of a => type as the type of some actual argument the function is applied to.
The "thin arrow" is used for function types (t1 -> t2 being the type of a function that takes a value of type t1 and produces a value of type t2).
The "fat arrow" is used for type constraints. It separates the list of type constraints on a polymorphic function from the rest of the type. So given Floating a => a -> a, we have the function type a -> a, the type of a function that can take arguments of any type a and produces a result of that same type, with the added constraint Floating a, meaning that the function can in fact only be used with types that implement the Floating type class.
the -> is the constructor of functions and the => is used to constraints, a sort of "interface" in Haskell called typeclass.
A little example:
sum :: Int -> Int -> Int
sum x y = x + y
that function only allows Int types, but if you want a huge int or a small int, you probably want Integer, and how to tell it to use both?
sum2 :: Integral a => a -> a -> a
sum2 x y = x + y
now if you try to do:
sum2 3 1.5
it will give you an error
also, you may want to know if two data are equals, you want:
equals :: Eq a => a -> a -> Bool
equals x y = x == y
now if you do:
3 == 4
that's ok
but if you create:
data T = A | B
equals A B
it will give to you:
error:
• No instance for (Eq T) arising from a use of ‘equals’
• In the expression: equals A B
In an equation for ‘it’: it = equals A B
if you want for that to work, you must just do:
data T = A | B deriving Eq
equals A B
False

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.

Determining the type of a function

I am trying to figure out the way Haskell determines type of a function. I wrote a sample code:
compareAndIncrease a b =
if a > b then a+1:b:[]
else a:b:[]
which constructs a list basing on the a > b comparison. Then i checked its type with :t command:
compareAndIncrease :: (Ord a, Num a) => a -> a -> [a]
OK, so I need a typeclass Ord for comparison, Num for numerical computations (like a+1). Then I take parameters a and b and get a list in return (a->a->[a]). Everything seems fine. But then I found somewhere a function to replicate the number:
replicate' a b
| a ==0 = []
| a>0 = b:replicate(a-1) b
Note that normal, library replicate function is used inside, not the replicate' one. It should be similar to compareAndIncrease, because it uses comparison, numerical operations and returns a list, so I thought it would work like this:
replicate' :: (Ord a, Num a) => a -> a -> [a]
However, when I checked with :t, I got this result:
replicate' :: Int -> t -> [t]
I continued fiddling with this function and changed it's name to repval, so now it is:
Could anyone explain to me what is happening?
GHCi is a great tool to use here:
*Main> :type replicate
replicate :: Int -> a -> [a]
You define replicate' in terms of replicate (I rename your variables for clarity):
replicate' n e
| -- blah blah blah
| n > 0 = e : replicate (n - 1) e
Since you call replicate (n - 1), the type checker infers that n - 1 must have type Int, from which it infers that n must have type Int, from which it infers that replicate' has type Int -> a -> [a].
If you wrote your replicate' recursively, using replicate' inside instead of replicate, then you would get
*Main> :type replicate'
replicate' :: (Ord a, Num a) => a -> a1 -> [a1]
Edit
As Ganesh Sittampalam points out, it's best to constrain the type to Integral as it doesn't really make sense to replicate a fractional number of times.
The key flaw in your reasoning is that replicate actually only takes Int for the replication count, rather than a more general numeric type.
If you instead used genericReplicate, then your argument would be roughly valid.
genericReplicate :: Integral i => i -> a -> [a]
However note that the constraint is Integral rather than Num because Num covers any kind of number including real numbers, whereas it only makes sense to repeat something an integer number of times.

Resources