Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Benefits of where notation in Haskell

What are the pros and cons of explicit function definition as opposed to where notation in Haskell?

Explicit function definition:

foo :: Integer -> Integer
foo a = bar a
  where
    bar :: Integer -> Integer
    bar a = Some code here

as opposed to:

foo :: Integer -> Integer
foo a = bar a

bar :: Integer -> Integer
bar a = Some code here

Why would I use one over the other? Is there anything to be aware of with regards to efficiency? Security? Code reusability? Code readability?

like image 340
Abraham P Avatar asked Jan 10 '23 23:01

Abraham P


1 Answers

If your auxiliary function is not going to be used anywhere else, it's better not to pollute the namespace and use a local definition.

When your outer function has only one top-level "pattern", the where clause can simplify the definition of the auxiliary function because the parameters of the outer function will be in scope.

outer x v z f = undefined
    where 
        inner i = i + x + v + z + f

versus

outer x v z f = undefined

inner x v z f i = i + x + v + z + f

If your function has more than one top-level "pattern", then you can't share bindings across patters using where. You have to define a top-level binding.

Certain ways of using where can incur in non-obvious performance penalties. This definition (taken from the HaskellWiki article on let vs where)

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

is slower than this one:

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

and also slower than defining fib' at the top-level.

The reason is that, in the first definition, a new fib' is created for each invocation of fib. Explained here.

like image 187
danidiaz Avatar answered Jan 21 '23 02:01

danidiaz