Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell underscore vs. explicit variable

Tags:

haskell

I've been learning Haskell for a few weeks, and I have a question about the use of the underscore (_) as a function parameter. I think my question will be better asked with a specific example. Let's say I want to define a function that extracts the element of a list based on the provided index—yes, I realize (!!) is already pre-defined. The two ways that I can define the function (I'm sure there are more) are the following:

Version 1

indexedElement             :: [a] -> Int -> a
indexedElement xs n | n < 0 = error "Index can not be negative."
indexedElement [] n         = error "Index must be smaller than the length of the list."
indexedElement (x:xs) 0     = x
indexedElement (x:xs) n     = indexedElement xs (n - 1)

Version 2

indexedElement            :: [a] -> Int -> a
indexedElement _ n | n < 0 = error "Index can not be negative."
indexedElement [] _        = error "Index must be smaller than the length of the list."
indexedElement (x:_) 0     = x
indexedElement (_:xs) n    = indexedElement xs (n - 1)

The two versions are obviously very similar. The only difference between the two is the use of an explicit variable or an underscore. To me _ means that literally anything can be written there while an explicit variable like n makes it more obvious that the argument must be an integer. For that reason, I prefer Version 1; but the GHC source code for (!!) is written like Version 2. Is there a functional advantage of the second version? If not, would "hardcore" Haskell programmers take issue with Version 1? I understand the importance of having a consistent way of writing code, so I try to follow the "unwritten rules" for programming in a particular language. This is an example where I much prefer the first version though, and I don't think it makes the code any more difficult to read. I don't know if it's due to my background in pure math or what, but I'd like to hear what you more-seasoned-Haskell vets think.

like image 394
philomathic_life Avatar asked Nov 24 '15 20:11

philomathic_life


People also ask

What does the underscore mean in Haskell?

Often an underscore character in Haskell code represents something we don't care about or don't know about – whether it's a wildcard, a hole, or a discarded result. Underscores appear both in types and in terms.

What does -> mean in Haskell?

(->) is often called the "function arrow" or "function type constructor", and while it does have some special syntax, there's not that much special about it. It's essentially an infix type operator. Give it two types, and it gives you the type of functions between those types.

What does ++ do Haskell?

The ++ operator is the list concatenation operator which takes two lists as operands and "combines" them into a single list.

Does Haskell evaluate left to right?

The evaluation strategy of Haskell is called “lazy evaluation”. This means it only evaluates arguments of functions when they are needed and from left to right – this is called an “outermost leftmost” evaluation or a “by need” evaluation strategy – and, in addition, it “shares” evaluations of subexpressions.


1 Answers

Is there a functional advantage of the second version?

I don't think they have any operational difference. But I find the second version more readable. _ indicates that it isn't used at all. So while reading the code, I can just ignore it and just concentrate on the other parameters. Whereas in the first version, I will be thinking that n is defined but maybe the author forgot to use it ? Or maybe the argument isn't required. The second version just avoids this kind of mental overload. But this is just my opinion. :)

In fact, if you enable the warning flag (-Wall) and compile your code, it will throw warning for your first version:

[1 of 1] Compiling Main             ( code.hs, code.o )

code.hs:2:16: Warning: Defined but not used: ‘xs’

code.hs:3:19: Warning: Defined but not used: ‘n’

code.hs:4:19: Warning: Defined but not used: ‘xs’

code.hs:5:17: Warning: Defined but not used: ‘x’

code.hs:8:17: Warning: Defined but not used: ‘xs’
like image 154
Sibi Avatar answered Sep 22 '22 01:09

Sibi