Can you handle both Int and Float while defining a function in Haskell? - haskell

I'm working on a Haskell problem to try and learn the language. I'm trying to recursively add all of the elements in a list, so:
[5,5] -> 10 and [5.0, 5.0] -> 10.0
I know how to recursively solve this, but my question is, how do you handle both Ints and Floats when defining a function? Right now I have:
add :: [Int] -> Int
which doesn't work for float. Thank you in advance for the help.

As indicated in the comments, you're looking for a typeclass. In this particular case, since you want to add numbers together, you want the Num typeclass, which (among other things) provides the addition function
(+) :: Num a => a -> a -> a
So your signature should look like
add :: Num a => [a] -> a
and the function can be written recursively
add [] = 0
add (x:xs) = x + add xs
Note that integer literals, such as 0 in this example, are internally treated as Num a => a. Effectively, the Haskell compiler will compile the number 0 to fromInteger (0 :: Integer), where fromInteger is another function in the Num typeclass. Hence, integer literals are polymorphic.
Finally, while there's nothing wrong with this implementation, the function you're looking at actually comes built-in to Haskell. It's called sum.
sum :: (Foldable t, Num a) => t a => a
Note that Foldable is a typeclass for, fittingly, things that can be folded over. The list type [] is an example of a Foldable.

Related

What does " Non type-variable argument in the constraint" really mean?

For example:
map (+1) 2
in ghci yields
<interactive>:23:1: error:
* Non type-variable argument in the constraint: Num [b]
(Use FlexibleContexts to permit this)
* When checking the inferred type
it :: forall b. (Num b, Num [b]) => [b]
I've seen many questions similar to mine, but all seem only to answer what we can deduce from this (that the type of the second argument to map is wrong), and how to fix it - but not what error actually means . Where do things go wrong precisely?
The error arises during the type-deduction of your statement.
Since
(+1) is of type Num a => a -> a
2 is of type Num a => a
map is of type (a -> b) -> [a] -> [b]
We know that map (+1) has to be of type (Num b) => [b] -> [b], and therefore map (+1) 2 of type (Num b, Num [b]) => [b]. But [b] is not just a type-variable, it's List of some type variable, where list is a data constructor. In an alternative version of Haskell where no syntactic sugar for lists exists, we might write (Num b, Num (List b)).
This is a problem because by default, Haskell does not support non type-variable arguments for constraints. So the precise nature of the problem is not that Haskell doesn't know how to map over numbers - it's that it doesn't allow values of the type that our function call produces.
But that rule isn't strictly needed. By adding -XFlexibleContexts when calling ghci, types of the sort that our method produces are now allowed. The reason for this is that the literal 2 in Haskell doesn't really represent a number - it represents an object of type Num a => a, which is constructed from the Integral 2 using fromIntegral. So the statement map (+1) 2 is equivalent to map (+1) (fromIntegral (2::Integer)). This means that the literal "2" can represent anything, given the proper instantiation - including lists.
2 has the type Num a => a; we haven't specified what a is, except that it has to have a Num instance.
map (+1) has the type Num b => [b] -> [b]; we have specified what b is, except it has to have a Num instance.
When we determine the type of map (+1) 2, we are basically unifying Num a ~ Num b => [b].
2 :: Num a => a
map (+1) :: Num b => [b] -> [b]
map (+1) 2 :: (Num b, Num [b]) => [b]
And this is the problem. Num requires a type variable like a or b, not a polymorphic type like [b], as its argument.
Here’s an actual answer:
GHC tries to infer the types by itself, and failed, or in GHC lingo:
When checking the inferred type …
Basically the conflict is:
• GHC is happy to have any value as a parameter for map (+1), as long as it is compatible with its type. And map (+1) wants a list of numbers, since + wants two numbers and 1 already is one number, and map always wants a list of values compatible with that.
• And here’s the kicker: GHC is happy to have 2 be any type! Because to save you the hassle of always having to specify if a literal 2 is of a certain type, GHC just treats numeric literals as Integer and replaces it with fromInteger 2. So since fromInteger is from the class Num, 2 can be anything that implemented that class Num! So 2 could be a list too!
So GHC is stuck trying to fit those things together, and tells you:
“It needs to be some value, that is a number. … And where the list of those values is also a number!”
Or in Haskell:
it :: forall b. (Num b, Num [b]) => [b]
But there is no instance that makes lists numbers!
Or in GHC lingo:
Non type-variable argument in the constraint: Num [b]
That’s why you nowadays get this, yes definitely badly designed and confusing error message.
(Almost all GHC error messages are a cruel joke. The best thing you can do to understand them, is to read them bottom to top! And know all of Haskell’s type system freedoms and the GHC extensions that are forcing GHC to not make assumptions that would make these errors a much simpler sub-class of errors otherwise.)
Obviously, you’d normally just replace 2 with an actual list of some sort. But we’re not going to do that here. Since GHC wants crazy, GHC shall get crazy:
Silly resolution
So since it leaves us the option of making lists (of numbers) numbers, that’s what we shall do:
instance Num b => Num [b] where
(+) = zipWith (+)
(*) = zipWith (*)
abs = map abs
signum = map signum
fromInteger i = [fromInteger i]
-- or repeat [fromInteger i], if we’re evil. ;)
negate = map negate
So now, it works perfectly fine:
> map (+1) 2
[3]
Since 2 becomes fromInteger 2 :: Num a => [a], which puts 2 in a list ([2]), and then map (+1) is happy and turns it into [2+1]. Which evaluates to [3].
This possibility is why the error message wasn’t a much simpler
“Error: 2 is not a list, but map expects a list!”.

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
...

How can an arbitrary Num contain any other numeric type?

I'm just starting with Haskell, and I thought I'd start by making a random image generator. I looked around a bit and found JuicyPixels, which offers a neat function called generateImage. The example that they give doesn't seem to work out of the box.
Their example:
imageCreator :: String -> IO ()
imageCreator path = writePng path $ generateImage pixelRenderer 250 300
where pixelRenderer x y = PixelRGB8 x y 128
when I try this, I get that generateImage expects an Int -> Int -> PixelRGB8 whereas pixelRenderer is of type Pixel8 -> Pixel8 -> PixelRGB8. PixelRGB8 is of type Pixel8 -> Pixel8 -> Pixel8 -> PixelRGB8, so it makes sense that pixelRenderer is doing some type inference to determine that x and y are of type Pixel8. If I define a type signature that asserts that they are of type Int (so the function gets accepted by generateImage, PixelRGB8 complains that it needs Pixel8s, not Ints.
Pixel8 is just a type alias for Word8. After some hair pulling, I discovered that the way to convert an Int to a Word8 is by using fromIntegral.
The type signature for fromIntegral is (Integral a, Num b) => a -> b. It seems to me that the function doesn't actually know what you want to convert it to, so it converts to the very generic Num class. So theoretically, the output of this is a variable of any type that fits the type class Num (correct me if I'm mistaken here--as I understand it, classes are kind of like "interfaces" where types are more like classes/primitives in OOP). If I assign a variable
let n = fromIntegral 5
:t n -- n :: Num b => b
So I'm wondering... what is 'b'? I can use this variable as anything, and it will implicitly cast to any numeric type, as it seems. Not only will it implicitly cast to a Word8, it will implicitly cast to a Pixel8, meaning fromPixel effectively gets turned from (as I understood it) (Integral a, Num b) => a -> b to (Integral a) => a -> Pixel8 depending on context.
Can someone please clarify exactly what's happening here? Why can I use a generic Num as any type that fits Num, both mechanically and "ethically"? I don't understand how the implicit conversion is implemented (if I were to create my own class, I feel like I would need to add explicit conversion functions). I also don't really know why this works; here I can use a pretty unsafe type and convert it implicitly to anything else. (for example, fromIntegral 50000 gets translated to 80 if I implicitly convert it to a Word8)
A common implementation of type classes such as Num is dictionary-passing. Roughly, when the compiler sees something like
f :: Num a => a -> a
f x = x + 2
it transforms it into something like
f :: (Integer -> a, a -> a -> a) -> a -> a
-- ^-- the "dictionary"
f (dictFromInteger, dictPlus) x = dictPlus x (dictFromInteger 2)
The latter basically says: "pass me an implementation for these methods of class Num for your type a, and I will use them to produce a function a -> a for you".
Values such as your n :: Num b => b are no different. They are compiled into things such as
n :: (Integer -> b) -> b
n dictFromInteger = dictFromInteger 5 -- roughly
As you can see, this turns innocent-looking integer literals into functions, which can (and does) impact performance. However, in many circumstances the compiler can realize that the full polymorphic version is not actually needed, and remove all the dictionaries.
For instance, if you write f 3 but f expects Int, the "polymorphic" 3 can be converted at compile time. So type inference can aid the optimization phase (and user-written type annotation can greatly help here). Further, some other optimizations can be triggered manually, e.g. using the GHC SPECIALIZE pragma. Finally, the dreaded monomorphism restriction tries hard to force non-functions to remain non-functions after translation, at the cost of some loss of polymorphism. However, the MR is now being regarded as harmful, since it can cause puzzling type errors in some contexts.

How to Interpret (Eq a)

I need to create a function of two parameters, an Int and a [Int], that returns a new [Int] with all occurrences of the first parameter removed.
I can create the function easily enough, both with list comprehension and list recursion. However, I do it with these parameters:
deleteAll_list_comp :: Integer -> [Integer] -> [Integer]
deleteAll_list_rec :: (Integer -> Bool) -> [Integer] -> [Integer]
For my assignment, however, my required parameters are
deleteAll_list_comp :: (Eq a) => a -> [a] -> [a]
deleteAll_list_rec :: (Eq a) => a -> [a] -> [a]
I don't know how to read this syntax. As Google has told me, (Eq a) merely explains to Haskell that a is a type that is comparable. However, I don't understand the point of this as all Ints are naturally comparable. How do I go about interpreting and implementing the methods using these parameters? What I mean is, what exactly are the parameters to begin with?
#groovy #pelotom
Thanks, this makes it very clear. I understand now that really it is only asking for two parameters as opposed to three. However, I still am running into a problem with this code.
deleteAll_list_rec :: (Eq a) => a -> [a] -> [a]
delete_list_rec toDelete [] = []
delete_list_rec toDelete (a:as) =
if(toDelete == a) then delete_list_rec toDelete as
else a:(delete_list_rec toDelete as)
This gives me a "The type signature for deleteAll_list_rec
lacks an accompanying binding" which makes no sense to me seeing as how I did bind the requirements properly, didn't I? From my small experience, (a:as) counts as a list while extracting the first element from it. Why does this generate an error but
deleteAll_list_comp :: (Eq a) => a -> [a] -> [a]
deleteAll_list_comp toDelete ls = [x | x <- ls, toDelete==x]
does not?
2/7/13 Update: For all those who might stumble upon this post in the future with the same question, I've found some good information about Haskell in general, and my question specifically, at this link : http://learnyouahaskell.com/types-and-typeclasses
"Interesting. We see a new thing here, the => symbol. Everything before the => symbol is >called a class constraint. We can read the previous type declaration like this: the >equality function takes any two values that are of the same type and returns a Bool. The >type of those two values must be a member of the Eq class (this was the class constraint).
The Eq typeclass provides an interface for testing for equality. Any type where it makes >sense to test for equality between two values of that type should be a member of the Eq >class. All standard Haskell types except for IO (the type for dealing with input and >output) and functions are a part of the Eq typeclass."
One way to think of the parameters could be:
(Eq a) => a -> [a] -> [a]
(Eq a) => means any a's in the function parameters should be members of the
class Eq, which can be evaluated as equal or unequal.*
a -> [a] means the function will have two parameters: (1) an element of
type a, and (2) a list of elements of the same type a (we know that
type a in this case should be a member of class Eq, such as Num or
String).
-> [a] means the function will return a list of elements of the same
type a; and the assignment states that this returned list should
exclude any elements that equal the first function parameter,
toDelete.
(* edited based on pelotom's comment)
What you implemented (rather, what you think you implemented) is a function that works only on lists of Integers, what the assignment wants you to do is create one that works on lists of all types provided they are equality-comparable (so that your function will also work on lists of booleans or strings). You probably don't have to change a lot: Try removing the explicit type signatures from your code and ask ghci about the type that it would infer from your code (:l yourfile.hs and then :t deleteAll_list_comp). Unless you use arithmetic operations or similar things, you will most likely find that your functions already work for all Eq a.
As a simpler example that may explain the concept: Let's say we want to write a function isequal that checks for equality (slightly useless, but hey):
isequal :: Integer -> Integer -> Bool
isequal a b = (a == b)
This is a perfectly fine definition of isequal, but the type constraints that I have manually put on it are way stronger than they have to. In fact, in the absence of the manual type signature, ghci infers:
Prelude> :t isequal
isequal :: Eq a => a -> a -> Bool
which tells us that the function will work for all input types, as long as they are deriving Eq, which means nothing more than having a proper == relation defined on them.
There is still a problem with your _rec function though, since it should do the same thing as your _comp function, the type signatures should match.

How do I determine the type of constant expressions in Haskell?

I am trying to revise for my functional programming exam, and am stumped on the first questions on past papers, and yes, we arent allowed solution sheets, here is an example of the 1st question on a past paper.
For each of the following expressions give its type in Haskell (for an expression that has many types, just give one type).
(True, "hello", 42)
[42, 4, 2]
length [True]
filter even
I think personally that the answer for one and two would be a tuple of bool, String and int and a list of ints respectively, is this correct to assume? and secondly how would you answer 3 and 4, i am sure length True just outputs a list of all elements that are of that length, and that filter even just alters a list of ints to a list that are of all even numbers, though how could i show this as an answer?
If you want to get types of variables offline with ghci you have to type
:t expression
if you want to create variables in ghci, you have to use let without using 'in' (as in do notation for monads, I don't know if you have seen them yet) :
let var = expr
If you check it all by yourself, you should be able to remember it more easily for your exams. (good luck for it ;))
length [True] will be Int, and it would return 1. You can check that with ghci or lambdabot.
filter even will be (Integral a) => [a] -> [a]
for example, [Int] -> [Int]
And I think this is kind of pointless because lambdabot can tell all those things to you.
To be precise, the type of [42, 4, 2] is going to be
Num a => [a]
This is because an integer literal in Haskell is treated as having an implicit "fromIntegral" in front of it, so the real expression is [fromIntegral 42, fromIntegral 4, fromIntegral 2].
"fromIntegral" is part of the Num class, and has the type
fromIntegral :: (Integral a, Num b) => a -> b
This says that it converts an instance of some Integral type (i.e. Int or Integer) into an arbitrary other numeric type (Int, Float, Double, Complex ...). This is why you can say something like "43.2 + 1" without getting a type error.
"length [True]" is going to have type Int, because "length" has type "[a] -> Int", and the argument (a list of Bool) is provided.
"filter even" is a little bit more complicated. Start with the type of "filter":
filter :: (a -> Bool) -> [a] -> [a]
The first parameter (the bit in brackets) is itself a function that takes a list item and returns a Bool. Remember that the "->" operator in Haskell types is right associative, so if you put in the implied brackets you see that the type is:
filter :: (a -> Bool) -> ([a] -> [a])
In other words if you give it the first argument, you get back a new function that expects the second argument. In this case the first argument is:
even :: (Integral a) => a -> Bool
This introduces a slight wrinkle: "even" requires its argument to be an Integral type (i.e. Int or Integer, as above), so this constraint has to be propagated to the result. If it were not then you could write this:
filter even "foo"
Hence the answer is:
filter even :: (Integral a) => [a] -> [a]
You can see that the Integral constraint comes from the type of "even", while the rest of the type comes from "filter".

Resources