I'm studying Haskell using the book "Haskell Programming from First Principles", and towards the end of Chapter 4, "Basic datatypes", I've come across something that confused me. The book mentions a function length
and says that it works on Lists
s. Everything is fine with that, but when I try this length
function with various Tuple
s, what I see confused me:
First, let's see the type of length
:
:t length
length :: Foldable t => t a -> Int
OK, so I read above as "takes a Foldable, which I think as a list for convenience, and returns an Int, that is the number of elements in the list." Hence my first confusion: Why does the the following work at all:
length (1, 1)
1
Because to me, it seems like I've just passed a tuple with two elements to length
, and it returned 1. Is tuple a list? Is tuple Foldable? And of course, why 1
?
Now I go one step further:
length (1, 1, 1)
<interactive>:6:1:
No instance for (Foldable ((,,) t0 t1))
arising from a use of ‘length’
In the expression: length (1, 1, 1)
In an equation for ‘it’: it = length (1, 1, 1)
<interactive>:6:9:
No instance for (Num t0) arising from the literal ‘1’
The type variable ‘t0’ is ambiguous
Note: there are several potential instances:
instance Num Integer -- Defined in ‘GHC.Num’
instance Num Double -- Defined in ‘GHC.Float’
instance Num Float -- Defined in ‘GHC.Float’
...plus two others
In the expression: 1
In the first argument of ‘length’, namely ‘(1, 1, 1)’
In the expression: length (1, 1, 1)
<interactive>:6:12:
No instance for (Num t1) arising from the literal ‘1’
The type variable ‘t1’ is ambiguous
Note: there are several potential instances:
instance Num Integer -- Defined in ‘GHC.Num’
instance Num Double -- Defined in ‘GHC.Float’
instance Num Float -- Defined in ‘GHC.Float’
...plus two others
In the expression: 1
In the first argument of ‘length’, namely ‘(1, 1, 1)’
In the expression: length (1, 1, 1)
Another try:
length (1::Int, 1::Int, 1::Int)
<interactive>:7:1:
No instance for (Foldable ((,,) Int Int))
arising from a use of ‘length’
In the expression: length (1 :: Int, 1 :: Int, 1 :: Int)
In an equation for ‘it’: it = length (1 :: Int, 1 :: Int, 1 :: Int)
But the following works:
length (1::Int, 1::Int)
1
Is there any good explanation for the behavior I'm observing above? Am I misreading the type of length
? Or is there something else going on behind the scenes?
Foldable
works with only the last part of the tuple and the fact that there is aFoldable
instance for 2-tuples and only for those - I recommend you just take it as is - if you want you can find plenty of discussions around this - here is an example: Haskell Foldable Wats – Cerenkov