views:

409

answers:

3

I hope this is a valid post for these forums

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?

thanks for your time, and if this shouldn't be posted here please delete and accept my apologies

+1  A: 

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.

alamar
GHCi can tell all those things too you just as well.
Rayne
+5  A: 

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 ;))

Raoul Supercopter
let isn't "as in monads"; regular functions can use let, likef x = let y = x * x in x + y
alamar
Ah ok, I've been misunderstood, I meant to use them like in the do notation...
Raoul Supercopter
+1  A: 

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

Paul Johnson