1

Given this function

let readInput() = 
  Seq.initInfinite (fun _ -> Console.ReadLine())
 |> Seq.takeWhile (fun s -> s <> null) `
 |> Seq.map int`

is the _ in the function called by Seq.initInfinite a wild card, so that anything can be read off STDIN?

I've got a couple of different F# books, and am looking on the Internet, but can only find references to _ being used in unpacking tuple values.

  • Not quite. Seq.initInfinite expects to be passed a function of type int-> 'T, which it then calls multiple times with an increasing index. In this case, the function we want it to call is fun _ -> Console.ReadLine(), ie a function that ignores its parameter and returns a string from Console.ReadLine(). _ can be used anywhere that you want a "throw-away" variable or parameter, ie one that gets assigned, but is never read, as above. In that regard it's very similar to the _ in wildcard patterns. – David Arno Sep 20 '16 at 20:19
  • @DavidArno Thank you for confirming that "" acts very much like when Clojure parameters are destructured and the binding isn't important. I often use "" when I want a function to execute. Thanks, cmn – octopusgrabbus Sep 20 '16 at 20:54

2 Answers2

5

is the _ in the function called by Seq.initInfinite a wild card

Yes.

so that anything can be read off STDIN

No. Seq.initInfinite passes an int, indicating the current index. For example, you can use it to create an infinite sequence of only even numbers: Seq.initInfinite (fun i -> i * 2). But in your case, you don't care about the index, so using _ is appropriate here.

Using the wildcard here does not affect the Console.ReadLine() in any way.

svick
  • 10,049
2

"Don't care" underscore identifiers are effectively used as wildcard patterns. The difference with a variable that would happen to be named _ is that each occurrence of _ represents a different identifier; consequently: (1) you can't reference the same _ twice and thus (2) no warning is emitted for lack of usage of _, whereas another name like dummy would probably raise a warning for never being used.

The don't care symbol is is present in languages with built-in pattern matching because sometimes you only want to match a value against a particular structure and the actual content is not important. This happens mostly in F#, OCaml, Haskell and notably Prolog, but other languages might provide this too.

Here is a simplistic example in OCaml:

let empty = function [] -> true | _ :: _ -> false;;

Here above, you just want to match empty lists vs. non-empty lists. You have two different patterns to dissociate both cases, but the actual content of non-empty lists won't be used, so you just place underscores.

See also section 2.4 Identifiers and Operators of Haskell specification:

However, “_” all by itself is a reserved identifier, used as wild card in patterns.

Thanks to svick's comment, I don't have to search much for the relevant quote for :

Wildcard Pattern

The wildcard pattern is represented by the underscore (_) character and matches any input, just like the variable pattern, except that the input is discarded instead of assigned to a variable. The wildcard pattern is often used within other patterns as a placeholder for values that are not needed in the expression to the right of the -> symbol. The wildcard pattern is also frequently used at the end of a list of patterns to match any unmatched input.

coredump
  • 5,945