I have the following piece of code:
if File.Exists(settingsFilePath) = false then
System.Console.WriteLine("Are you running BlogDotNet for the first time? (yes/no):");
match System.Console.ReadLine() with
| "yes" ->
try
()
with
| :? System.UnauthorizedAccessException -> System.Console.WriteLine("You don't have write permissions on the current directory, please move to another one!")
| :? System.IOException -> System.Console.WriteLine("Couldn't one or more of the create the necessary directories and files, an unknown IO related exception occured")
| "no" -> System.Console.WriteLine("Then you must be running blogctl while in a wrong directory,")
System.Console.WriteLine("please move to the correct directory first before attempting to issue any further blogctl commands")
| _ -> System.Console.WriteLine("Invalid answer, please answer with either 'yes' or 'no'")
else
match List.ofArray (System.Environment.GetCommandLineArgs().[1..]) with
| [""] | ["help"] | ["--help"] | ["-h"] -> ()
| _ -> System.Console.WriteLine("Invalid command or command with invalid arguments, run 'blogctl help' to get a list of the available commands")
System.Console.WriteLine("and information about their usage")
The compiler keeps complaining with "error FS0597: Successive arguments should be separated by spaces or tupled, and arguments involving function or method applications should be parenthesized" at the last line and at line 12. Now as you can see at the code listing above those lines are indeed incorrectly indented, but when I copied them from my editor (Visual Studio Code) they were correctly indented. I have tried multiple times to remove the indentation and indent them again, to no avail, the compiler just keeps complaining. When I put the 2 Console.WriteLine() expressions on one line after the arrow and separate them by a semicolon the compiler stops complaining.
Related
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.
I have a scenario where a statement/rule can appear anywhere in the whole code. This statement starts with a keyword and if this keyword appears, i need to skip the whole content till i reach ';'.
I tried addressing this by defining a terminal rule as below:
terminal stmt: 'TEMP' -> ';';
However my whole code is case insensitive and terminal rules are not. How do i make terminal rule case insensitive? Or is there a alternative way in which all my conditions for this statement are satisfied?
you can do the following
terminal THINGY:
('T' | 't') ('E' | 'e')
('M' | 'm') ('P' | 'p')->";";
My Lexer is supposed to distinguish brackets and maintain a stack of opened brackets during lexing. For this I specified a helper function in my fsl file like this:
let updateBracketStack sign = // whenever a bracket is parsed, update the stack accordingly
match sign with
| '[' -> push sign
| '{' -> push sign
| ']' -> if top() = '[' then pop() else ()
| '}' -> if top() = '{' then pop() else ()
| _ -> ()
The stack of course is a ref of char list. And push, top, pop are implemented accordingly.
The problem is that everything worked up until I added the { character. Now FsLex simply dies with error: parse error
If I change the characters to strings, i.e. write "{" FsLex is fine again, so a workaround would be to change the implementation to a stack of strings instead of characters.
My question is however, where does this behaviour come from? Is this a bug if FsLex?
FsLex's parser is generated using FsLexYacc. The message "parse error" means the lexing (of your .fsl file) until error position is succeeded but parsing is failed at that position. To find the root cause you will need to post full input text to FsLex.
This is only guess. FsLex could be confused by '{' character since it is also open token for embedded code block? Or your input text contains some special unicode characters but it looks like whitespace on editor?
One possible workaround is, to create another module and .fs file, LexHelper module in LexHelper.fs, and place your helper functions in it, and open it from .fsl file.
EDIT
Looking at the source code of FsLexYacc, it doesn't handle } character enclosed by single-quotes in embedded F# code, but does when enclosed by double-quotes.
https://github.com/fsprojects/FsLexYacc/blob/master/src/FsLex/fslexlex.fsl
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"
I am currently connecting SQL server to robot framework, so i can read my data table name in robot. and I want to use for loop to check table name, somehow, ":FOR" loop keyword cannot found, but I have installed libraries such as operating-system, collections, string, built-in, diff-library and so on. anyone can help me why i cannot use for loop? any help will be appreciated.
The robot framework users guide has a whole section on how to use the for loop. From that section:
The syntax starts with :FOR, where colon is required to separate the
syntax from normal keywords. The next cell contains the loop variable,
the subsequent cell must have IN, and the final cells contain values
over which to iterate. These values can contain variables, including
list variables.
Here's an example from the user's guide, reformatted to use pipes (for clarity):
*** Test Cases ***
| Example 1
| | :FOR | ${animal} | IN | cat | dog
| | | log | ${animal}
| | | log | 2nd keyword
| | Log | Outside loop
Maybe you are not escaping indented cells; as the Tip in the documentation says. Try writing loops like this:
:FOR ${index} IN RANGE ${start} ${stop}
\ log to console index: ${index}
\ Call a Keyword