F# ignore missing ignore - f#

I am using F# often in a interactive way. I type statements in a script file in Visual Studio and press Alt + Enter to execute them in F# Interactive.
Very often I see the warning that I am ignoring the result of an expression. Of course I'm not, because I evaluate everything interactively.
Is there an option to turn this warning off?
Example:
let numbers = "151,160,137,91,90,15"
numbers.ToCharArray()
|> Array.filter (fun e-> e=',')
|> Array.length

F# Interactive has various options including one to suppress compiler warning messages:
--nowarn:<warning-list>
For more details see:
/nowarn (C# Compiler Options)
As an example:
match [] with | a::b -> 0
F# Interactive returns
Script.fsx(9,7): warning FS0025: Incomplete pattern matches on this expression.
For example, the value '[]' may indicate a case not covered by the pattern(s).
Microsoft.FSharp.Core.MatchFailureException:
The match cases were incomplete at <StartupCode$FSI_0003>.$FSI_0003.main#() in
C:\Users\Eric\Documents\Visual Studio2015\Projects\Workspace\Library2\Script.fsx:line 9
Stopped due to error
For
#nowarn "25"
match [] with | a::b -> 0
F# Interactive returns
Microsoft.FSharp.Core.MatchFailureException:
The match cases were incomplete at <StartupCode$FSI_0004>.$FSI_0004.main#() in
C:\Users\Eric\Documents\Visual Studio 2015\Projects\Workspace\Library2\Script.fsx:line 9
Stopped due to error
Notice the warning is now gone.
To use nowarn you need to know the warning number which are like:
warning FS0025
It is the last digits of the warning code that you want to use with #nowarn and do not forget the quotes around the number.
So for FS0025 it is #nowarn "25"

Related

FS0010: Unexpected keyword in binding

I am trying to follow the docs to create an f# program in Visual studio Code
When I highlight my code and press Alt Enter to run in the interactive window I get an error
Script.fsx(8,5):error FS0010: Unexpected keyword in binding. Expected incomplete structured construct at or before this point or other token.
[Update]
I tried several times to get this to work, highlighting the code as the image shows.
Strangely after leaving the computer an hour, I now can no longer repeat the problem.
The output visible in the interactive window suggests that your selection when you pressed Alt+Enter was different from the selection you're showing in the screenshot. More specifically, the selection you executed started with let isVowel (without leading spaces) and ended with word.[0] then.
Even more specifically, the code you tried to execute was this:
let isVowel (c: char) =
match c with
| 'a' | 'e' | 'i' |'o' |'u'
| 'A' | 'E' | 'I' | 'O' | 'U' -> true
|_ -> false
if isVowel word.[0] then
This code does not compile for several reasons. First, there is nothing after then. Second, the if is indented incorrectly: it needs to be indented either to the same position as match (in which case it will be considered part of isVowel definition) or to the same position as let isVowel (in which case it will be considered part of the same block as isVowel), but here it is neither - to the right of let isVowel, but to the left of match.
If you wanted to execute just the definition of isVowel, then you shouldn't have included the if in the selection.
If you wanted to execute the whole definition of toPigLatin, then you should have included the let toPigLatin line and the whole if/else expression.

Tests: check if tuple is returned

I am writing a test which checks response from gen_server. The response itself is either {profile, SomeProfileFromGenServer} or {error, ErrorResponse}
So I wanted to write a test which does:
Profile = mygenserver:get_profile(),
?assertEqual(Profile, {profile, SomeProfile})
As I don't really care about the SomeProfile value. But this says that SomeProfile is unbound :( Is there a way to fix it?
You can use ?assertMatch, with the first argument being a pattern:
?assertMatch({profile, _}, Profile)
assertMatch(GuardedPattern, Expr)
Evaluates Expr and matches the result against GuardedPattern, if testing is enabled. If the match fails, an informative exception will be generated; see the assert macro for further details. GuardedPattern can be anything that you can write on the left hand side of the -> symbol in a case-clause, except that it cannot contain comma-separated guard tests.
The main reason for using assertMatch also for simple matches, instead of matching with =, is that it produces more detailed error messages.
Examples:
?assertMatch({found, {fred, _}}, lookup(bloggs, Table))
?assertMatch([X|_] when X > 0, binary_to_list(B))

Compile-time constraint for complete pattern match

I'm looking for the warning number for incomplete pattern matches. Anyone know what it is?
More fully, I want to make FSC.EXE return incomplete pattern matches as compile-time errors rather than warnings + run-time exceptions. Does anyone know what the warning number for this is? Specifically, this relates to compiled .fs / interactive FSI .fsx REPL interaction.
The warning:
Incomplete pattern matches on this expression. For example, the value 'LaLaLa (_)' may indicate a case not covered by the pattern(s).
How to customise:
see "--warnaserror[+|-] []"
ref: https://msdn.microsoft.com/en-us/library/dd233171(v=vs.140).aspx
use --warnaserror+:25
To know which one it was I simply produced myself the warning using let f (Some x) = x which gaves me warning FS0025: Incomplete pattern matches on this expression. For e
xample, the value 'None' may indicate a case not covered by the pattern(s).
In a .Net Standard F# project you can also achieve this by adding an element to your fsproj file like so:
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<WarningsAsErrors>FS0025</WarningsAsErrors>
</PropertyGroup>

Why is using the base key word causing this error?

I am trying to do an example for Programming F# by O'Railey, Chris Smith page 53.
It is working with functions returning functions.
This line straight from the book in the VS2013 IDE Editor, FSI and LinqPad4 are giving an error:
Code:
let generatePowerOfFunc base = (fun exponent -> base ** exponent)
Error:
error FS0010: Unexpected keyword 'base' in pattern
What am I missing or is there something the author did not include that needs to be included.
I strongly suspect it's merely a matter of base not being a keyword when the book was written.
Try a different identifier:
let generatePowerOfFunc b = (fun exponent -> b ** exponent)
Assuming you've got the 2009 edition of Programming F#, that would be before F# 2.0 was released (although after 1.0). I'm trying to find out exactly when it was introduced as a keyword...
EDIT: Actually, looking at this version of the spec which was written in 2009, it looks like base was already a keyword at that point. I wonder whether the original code was written significantly before the book was published.
Either way, I think it's reasonable to treat it basically as an error, and using a valid identifier instead should be fine.
EDIT: It's actually listed in the book's errata:
Example 3-3 does not work as-is in VS 2010. "base" is apparently a keyword, so it should have been escaped or there is some voodoo to make it not a keyword that I've missed in the book. Line 2 of the example should look like this:
let generatePowerOfFunc ``base`` = (fun exponent -> ``base`` ** exponent);;
Alternatively, a different variable name should be chosen.
Note from the Author or Editor:
Thanks for the feedback, I must have missed the keyword being marked as reserved late in the product cycle.
In a future version of the book I'll have it read:
let generatePowerOfFunc baseValue = (fun exponent -> baseValue ** exponent);;
base in F# is a keyword, which refers to the parent class.
Either you can use double backticks as follows
let generatePowerOfFunc ``base`` = (fun exponent -> ``base`` ** exponent);;
or just change the name of the argument to something else.

When do you put double semicolons in F#?

This is a stupid question. I've been reading a couple books on F# and can't find anything that explains when you put ;; after a statement, nor can I find a pattern in the reading. When do you end a statement with double semi-colons?
In the non-interactive F# code that's not supposed to be compatible with OCaml, you shouldn't need to ever need double semicolon. In the OCaml compatible mode, you would use it at the end of a top-level function declaration (In the recent versions, you can switch to this mode by using files with .ml extension or by adding #light "off" to the top).
If you're using the command-line fsi.exe tool or F# Interactive in Visual Studio then you'd use ;; to end the current input for F#.
When I'm posting code samples here at StackOverflow (and in the code samples from my book), I use ;; in the listing when I also want to show the result of evaluating the expression in F# interactive:
Listing from F# interactive
> "Hello" + " world!";;
val it : string = "Hello world!"
> 1 + 2;;
val it : int = 3
Standard F# source code
let n = 1 + 2
printf "Hello world!"
Sometimes it is also useful to show the output as part of the listing, so I find this notation quite useful, but I never explained it anywhere, so it's great that you asked!
Are you talking about F# proper or about running F# functions in the F# Interactive? In F# Interactive ;; forces execution of the code just entered. other than that ;; does not have any special meaning that I know of
In F#, the only place ;; is required is to end expressions in the interactive mode.
;; is left over from the transition from OCaml, where in turn it is left over from Caml Light. Originally ;; was used to end top-level "phrases"--that is, let, type, etc. OCaml made ;; optional since the typical module consists of a series of let statements with maybe one statement at the end to call the main function. If you deviate from this pattern, you need to separate the statements with ;;. Unfortunately, in OCaml, when ;; is optional versus required is hard to learn.
However, F# introduces two relevant modifications to OCaml syntax: indentation and do. Top-level statements have to go inside a do block, and indentation is required for blocks, so F# always knows that each top-level statement begin with do and an indent and ends with an outdent. No more ;; required.
Overall, all you need to know is that [O']Caml's syntax sucks, and F# fixes a lot of its problems, but maintains a lot of confusing backward compatibility. (I believe that F# can still compile a lot of OCaml code.)
Note: This answer was based on my experience with OCaml and the link Adam Gent posted (which is unfortunately not very enlightening unless you know OCaml).
Symbol and Operator Reference (F#)
http://msdn.microsoft.com/en-us/library/dd233228(v=VS.100).aspx
Semi Colon:
•Separates expressions (used mostly in verbose syntax).
•Separates elements of a list.
•Separates fields of a record.
Double Semi Colon:
http://www.ffconsultancy.com/products/fsharp_journal/free/introduction.html
Articles in The F#.NET Journal quote F# code as it would appear in an interactive session. Specifically, the interactive session provides a > prompt, requires a double semicolon ;; identifier at the end of a code snippet to force evaluation, and returns the names (if any) and types of resulting definitions and values.
I suspect that you have seen F# code written when #light syntax wasn't enabled by default (#light syntax is on by default for the May 2009 CTP and later ones as well as for Visual Studio 2010) and then ;; means the end of a function declaration.
So what is #light syntax? It comes with the #light declaration:
The #light declaration makes
whitespace significant. Allowing the
developer to omit certain keywords
such as in, ;, ;;, begin, and end.
Here's a code written without #light syntax:
let halfWay a b =
let dif = b - a in
let mid = dif / 2 in
mid + a;;
and becomes with light syntax:
#light
let halfWay a b =
let dif = b - a
let mid = dif / 2
mid + a
As said you can omit the #light declaration now (which should be the case if you're on a recent CTP or Visual Studio 2010).
See also this thread if you want know more on the #light syntax: F# - Should I learn with or without #light?
The double semi-colon is used to mark the end of a block of code that is ready for evaluation in F# interactive when you are typing directly into the interactive session. For example, when using it as a calculator.
This is rarely seen in F# because you typically write code into a script file, highlight it and use ALT+ENTER to have it evaluated, with Visual Studio effectively injecting the ;; at the end for you.
OCaml is the same.
Literature often quotes code written as it would appear if it had been typed into an interactive session because this is a clear way to convey not only the code but also its inferred type. For example:
> [1; 2; 3];;
val it : int list = [1; 2; 3]
This means that you type the expression [1; 2; 3] into the interactive session followed by the ;; denoting the end of a block of code that is ready to be evaluated interactively and the compiler replies with val it : int list = [1; 2; 3] describing that the expression evaluated to a value of the type int list.
The double semicolon most likely comes from OCaml since that is what the language is based on.
See link text
Basically its for historical purposes and you need it for the evaluator (repl) if you use it.
There is no purpose for double semi-colons (outside of F# interactive). The semi-colon, according to MSDN:
Separates expressions (used mostly
in verbose syntax).
Separates
elements of a list.
Separates
fields of a record.
Therefore, in the first instance, ;; would be separating the expression before the first semi-colon from the empty expression after it but before the second semi-colon, and separating that empty expression from whatever came after the second semi-colon (just as in, say C# or C++).
In the instance of the list, I suspect you'd get an error for defining an empty list element.
With regards to the record, I suspect it would be similar to separating expressions, with the empty space between the semi-colons effectively being ignored.
F# interactive executes the entered F# on seeing a double semi-colon.
[Updated to cover F# interactive - courtesy of mfeingold)
The history of the double semicolon can be traced back to the beginnings of ML when semicolons were used as a separator in lists instead of commas. In this ICFP 2010 - Tribute to Robin Milner video around 50:15 Mike Gordon mentions:
There was a talk on F# where someone asked "Why is there double semicolon on the end of F# commands?" The reason is the separator in lists in the original ML is semicolons, so if you wanted a list 1;2;3; and put it on separate lines- if you ended a line with semicolon you were not ending the phrase, so using double semicolon meant the end of the expression. Then in Standard ML the separator for lists became comma, so that meant you could use single semicolons to end lists.

Resources