Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What, in Haskell, does an underscore preceding a variable mean?

Tags:

haskell

I was browsing the source of Data.Foldable, where I came accross Endo #. f, and upon clicking this link, was confronted with:

(#.) _f = coerce

Now, first, I don't know what coerce and the before-that mentioned Coercible is, however, it baffles me more what the _f could mean. I have searched "Haskell underscore before variable" and similar and have only found discussions about the _ pattern matching syntax.

like image 439
schuelermine Avatar asked Jun 05 '18 17:06

schuelermine


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 an underscore before a variable mean?

An underscore in front usually indicates an instance variable as opposed to a local variable. It's merely a coding style that can be omitted in favor of "speaking" variable names and small classes that don't do too many things. Follow this answer to receive notifications.

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 foo mean in Haskell?

Foo (pronounced FOO) is a term used by programmers as a placeholder for a value that can change, depending on conditions or on information passed to the program. Foo and other words like it are formally known as metasyntactic variables.


2 Answers

According to the Haskell spec, it is just another possible name for a variable. But the truth is a bit longer, because most Haskell developers write code specifically for GHC, and this is one of those times.

GHC has lots of helpful warnings; one is to warn you when you write a pattern that binds a variable that isn't used in the body of the function. It's pretty handy, and has caught a couple bugs of mine. However, it has a knock-on effect: if you write a function that uses some of the variables only in one clause or the other, you get a warning. For example, here is a very natural definition of foldr on lists:

 foldr f z [] = z
 foldr f z (x:xs) = x `f` foldr f z xs

Oops! We didn't use f in the first clause, and we'll get a warning. Okay, so it's easy enough to fix:

foldr _ z [] = z
foldr f z (x:xs) = x `f` foldr f z xs

Unfortunately now we've lost the information about what that first variable's role in the code is supposed to be. In this case, foldr is so familiar that it's no big loss, but in unfamiliar codebases with functions that take a lot of arguments, it can be nice to know what data is ignored by each "hole". So GHC adds a special rule: the warning about unused variables doesn't warn you about variable names that start with _ -- by analogy to the _ pattern that it also doesn't warn you about. So now I can write:

foldr _f z [] = z
foldr  f z (x:xs) = x `f` foldr f z xs

Now I get the best of both worlds: I get a nice warning if I forget to use a variable I bound, and I can still give the reader information about the meaning of the holes in patterns that I don't need for the current clause. (As a side note, I'd love an additional warning that reported if I do mistakenly use a variable starting with _, but I don't think it exists at the moment! It sounds stupid ("just don't type _ in a function body"), but I've found my editor's tab-completion occasionally inserting them for me, and it would be easy not to notice if you were coding quickly.)

like image 166
Daniel Wagner Avatar answered Sep 21 '22 10:09

Daniel Wagner


It's just a convention to mark an unused variable. As you see, _f isn't used in the definition of #., so it is marked with the underscore.

like image 33
Sebastian Redl Avatar answered Sep 22 '22 10:09

Sebastian Redl