Reputation:
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?
Upvotes: 0
Views: 945
Reputation: 17806
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".
Upvotes: 1
Reputation: 5114
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 ;))
Upvotes: 6
Reputation: 19343
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.
Upvotes: 1