20

There are two functions written in the Haskell wiki website:

Function 1

fib = (map fib' [0 ..] !!)
    where
      fib' 0 = 0
      fib' 1 = 1
      fib' n = fib (n - 1) + fib (n - 2)

Function 2

fib x = map fib' [0 ..] !! x
    where
      fib' 0 = 0
      fib' 1 = 1
      fib' n = fib (n - 1) + fib (n - 2)

What does the "!!" mean?

1
  • 14
    This is a very valid question if you don't realize that !! is just an operator. Coders new to haskell will not yet know that !! is not some special syntax they have not encountered. Let's be gentle with those new to our language. Commented Feb 24, 2014 at 5:44

2 Answers 2

31

This is actually more difficult to read then it would seem at first as operators in haskell are more generic then in other languages.

The first thing that we are all thinking of telling you is to go look this up yourself. If you do not already know about hoogle this is the time to become familiar with it. You can ask it either to tell you what a function does by name or (and this is even more cool) you can give it the type of a function and it can offer suggestions on which function implement that type.

Here is what hoogle tells you about this function (operator):

(!!) :: [a] -> Int -> a

List index (subscript) operator, starting from 0. It is an 
instance of the more general genericIndex, which takes an index     
of any integral type.

Let us assume that you need help reading this. The first line tell us that (!!) is a function that takes a list of things ([a]) and an Int then gives you back one of the thing in the list (a). The descriptions tells you what it does. It will give you the element of the list indexed by the Int. So, xs !! i works like xs[i] would in Java, C or Ruby.

Now we need to talk about how operators work in haskell. I'm not going to give you the whole thing here, but I will at least let you know that there is something more here then what you would encounter in other programming languages. Operators "always" take two arguments and return something (a -> b -> c). You can use them just like a normal function:

add x y
(+) x y -- same as above

But, by default, you can also use them between expression (the word for this is 'infix'). You can also make a normal function work like an operator with backtics:

x + y
x `add` y -- same as above

What makes the first code example you gave (especially for new haskell coders) is that the !! operator is used as a function rather then in a typical operator (infix) position. Let me add some binding so it is clearer:

-- return the ith Fibonacci number
fib :: Int -> Int  -- (actually more general than this but do't worry about it) 
fib i = fibs !! i
    where
      fibs :: [Int]
      fibs = map fib' [0 ..]

      fib' :: Int -> Int
      fib' 0 = 0
      fib' 1 = 1
      fib' n = fib (n - 1) + fib (n - 2)

You can now work your way back to example 1. Make sure you understand what map fib' [0 ..] means.

I'm sorry your question got down-voted because if you understood what was going on the answer would have been easy to look up, but if you don't know about operators as the exist in haskell it is very hard to mentally parse the code above.

1
  • Good answer, but based on the question probably needs to mention operator sections. Commented Apr 2, 2014 at 22:40
6

(!!) :: [a] -> Int -> a

List index (subscript) operator, starting from 0. It is an instance of the more general genericIndex, which takes an index of any integral type.

See here: http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-List.html#g:16

Not the answer you're looking for? Browse other questions tagged or ask your own question.