I have this simple F# function:
let compareNum x =
let y = 10
match x with
| _ when x = y -> 0
| _ when x > y -> 1
| _ when x < y -> -1
However, F# compiler gives me "Incomplete pattern matches on this expression" warning. In this case, all cases should cover every pattern.
I also see a similar example in "Pattern Matching" section in the 1st edition of Programming F# book by Chris Smith. So something might be changed in the later version of F#?
I think the answer to the previous question (and the comments -- "In general, it is an anti-pattern to have a when guard in the last pattern" -- by kimsk) explain the situation.
However, I would not say that having a guard in the last pattern is an anti-pattern - it is the easiest workaround, but I find this somewhat unfortunate, because the when pattern gives you useful information about the values you can expect - and that makes understanding the program easier. Last time I had this problem, I left it there, at least as a comment:
let compareNum x =
let y = 10
match x with
| _ when x = y -> 0
| _ when x > y -> 1
| _ (*when x < y*) -> -1
Related
F# uses the offside rule for ensuring correct indentation. If this rule isn't followed can it result in the incorrectness of the program or is it purely a styling guide?
For example given the code for pattern matching:
let f x = match x with
| 1 -> "pattern 1"
| 2 -> "pattern 2"
| _ -> "anything"
Note two of the lines are offside. I have ran the program by complying with the offside rule and not complying with it and I get the same output but just wanted another opinion.
Also what about for if statements?
let test x y =
if x = y
then "equals"
else "is greater than"
let x = test 1 2
printf "%s" x
Note the compiler does warn when the offside rule isn't not being complied with:
warning FS0058: Possible incorrect indentation: this token is offside of context started at position (1:13). Try indenting this token further or using standard formatting conventions.
The accepted answer will need to address the issue for both the pattern matching example and the if statement.
The behavior of Lightweight syntax is described in great detail in the F# spec, section 15.1.4 deals specifically with Offside lines. The description there is technical and concerned with lexical analysis for the F# parser implementation. Nonetheless, it has a couple of useful examples.
// The "|" markers in patterns must align.
// The first "|" should always be inserted.
let f () =
match 1+1 with
| 2 -> printf "ok"
| _ -> failwith "no!" <--syntax error
whereas in your example a warning is generated instead. So you should be able to trust the compiled program to work as intended.
For if/then/else/elif clauses a special dispensation is given in 15.1.9, while their branches are falling under permitted undentations, 15.1.10, so that this is possible:
let test x y =
if x = y
then
"equals"
else "is greater than"
Disclaimer/edit: this is a fairly simple question, but I'm asking it since I'm (still) often confused by evaluation order in F#, esp. with respect to newlines vs. spaces. Trial and error always gets me where I want to, but I don't think you can really understand a language if you have to resort to trial and error.
If I write:
let res x =
x * 1 = x
|> ignore
all's fine, but if I write:
let res x =
x * 1 = x && x * -1 = -x
|> ignore
then the compiler complains (it says it expects bool -> bool, not bool -> unit). I would have expected the newline to act as a separator here.
Adding parentheses helps, and putting it on one line shows that it is evaluated as (X && (Y |> Z)), where X and Y are boolean expressions and Z is any function.
Is this true? And is there a simpler way to find this out? Or better, when is whitespace a significant operator and when not?
To give another example:
let v = x |> fun x -> float x |> fun y -> true
Why is y here of type float and not of type int -> float? This may be obvious, and I sure have programmed thousands of lines that way, it even feels natural, but why?
If the only answer to give is "operator precedence and -> comes before |>", so be it. But I guess/hope there's some more academical or otherwise formal though behind all this (and I still find it odd that && has lower prio than |>, again, I don't understand why and in that case it feels counter-intuitive).
Looking at https://learn.microsoft.com/en-us/dotnet/articles/fsharp/language-reference/symbol-and-operator-reference/#operator-precedence it seems that && has higher precedence than |> so your guess is correct and you need to add parenthesis:
let res x =
(x * 1 = x && x * -1 = -x)
|> ignore
It looks like a new line doesn't act as a separator unless it has a let binding or fall in one of the rules listed here
For example if you take this expression:
let res =
5 + 1
.GetType()
You also get an error, because it applies the . operator to 1 not to the whole expression, so the precedence rules still holds, regardless of the newline.
The line before the else statement apparently was expecting a unit but got a boolean instead. I'm just starting out with F# but can't fathom this one.
I'm fighting the layout a bit as I've never used Stackoverflow before and the code box is still confusing me! The spacing in the original is indented, I believe, correctly.
let m = Dictionary<int, int>()
let rec fib i =
match i with
| 1 -> i
| 0 -> i
| _ ->
if m.ContainsKey(i) then
if m.[i] > 0 then
m.[i]
else
let x = fib(i - 1) + fib(i - 2)
m.Add(i, x)
m.[i]
If anyone can tell me how to keep the spacing in these posts I'd be grateful!
The last bit is slightly wrong - should be
if m.ContainsKey(i) then
if m.[i] > 0 then
m.[i]
else
let x = fib(i - 1) + fib(i - 2)
m.Add(i, x)
x
You are returning from within the if statement. You probably dont need the if m.[i] > 0 either. In this case you get
let m = Dictionary<int, int>()
let rec fib i =
match i with
| 1 -> i
| 0 -> i
| _ ->
if m.ContainsKey(i) then
m.[i]
else
let x = fib(i - 1) + fib(i - 2)
m.Add(i, x)
m.[i]
For formatting on Stackoverflow just paste the code in then highlight and press ctrl+k or hit the {} button to automatically put the section into code mode (code is indented four spaces past normal text)
Easy mistake to make if you're new to such kinds of languages. Keep in mind that F# is expression based, therefore an if-then-else clause is an expression that evaluates to something. In order for this to happen, the type checker requires all branches of an if expression to be of the same type, as with pattern matching. Moreover, if expressions missing a closing else branch are only valid if their branches are of type unit.
Keeping those things in mind, you can see that this snippet will not pass type checking on account of two reasons:
The nested if expression has branches that produce values of different types (namely int and unit) and
The outer if expression expects the inner one to have type unit.
Hope this helps :)
I was reading this post While or Tail Recursion in F#, what to use when? were several people say that the 'functional way' of doing things is by using maps/folds and higher order functions instead of recursing and looping.
I have this function that returns the item at position x in a list:
let rec getPos l c = if c = 0 then List.head l else getPos (List.tail l) (c - 1)
how can it be converted to be more functional?
This is a primitive list function (also known as List.nth).
It is okay to use recursion, especially when creating the basic building blocks. Although it would be nicer with pattern matching instead of if-else, like this:
let rec getPos l c =
match l with
| h::_ when c = 0 -> h
| _::t -> getPos t (c-1)
| [] -> failwith "list too short"
It is possible to express this function with List.fold, however the result is less clear than the recursive version.
I'm not sure what you mean by more functional.
Are you rolling this yourself as a learning exercise?
If not, you could just try this:
> let mylist = [1;2;3;4];;
> let n = 2;;
> mylist.[n];;
Your definition is already pretty functional since it uses a tail-recursive function instead of an imperative loop construct. However, it also looks like something a Scheme programmer might have written because you're using head and tail.
I suspect you're really asking how to write it in a more idiomatic ML style. The answer is to use pattern matching:
let rec getPos list n =
match list with
| hd::tl ->
if n = 0 then hd
else getPos tl (n - 1)
| [] -> failWith "Index out of range."
The recursion on the structure of the list is now revealed in the code. You also get a warning if the pattern matching is non-exhaustive so you're forced to deal with the index too big error.
You're right that functional programming also encourages the use of combinators like map or fold (so called points-free style). But too much of it just leads to unreadable code. I don't think it's warranted in this case.
Of course, Benjol is right, in practice you would just write mylist.[n].
If you'd like to use high-order functions for this, you could do:
let nth n = Seq.take (n+1) >> Seq.fold (fun _ x -> Some x) None
let nth n = Seq.take (n+1) >> Seq.reduce (fun _ x -> x)
But the idea is really to have basic constructions and combine them build whatever you want. Getting the nth element of a sequence is clearly a basic block that you should use. If you want the nth item, as Benjol mentioned, do myList.[n].
For building basic constructions, there's nothing wrong to use recursion or mutable loops (and often, you have to do it this way).
Not as a practical solution, but as an exercise, here is one of the ways to express nth via foldr or, in F# terms, List.foldBack:
let myNth n xs =
let step e f = function |0 -> e |n -> f (n-1)
let error _ = failwith "List is too short"
List.foldBack step xs error n
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
Looks like here in StackOveflow there is a group of F# enthusiasts.
I'd like to know better this language, so, apart from the functional programming theory, can you point me to the better starting points to start using the F# language? I mean, tutorials, how-tos, but first of all working samples to have the chance to start doing something and enjoy the language.
Thanks a lot
Andrea
Not to whore myself horribly but I wrote a couple F# overview posts on my blog here and here. Chris Smith (guy on the F# team at MS) has an article called 'F# in 20 minutes' - part 1 and part 2.
Note you have to be careful as the latest CTP of F# (version 1.9.6.0) has some seriously breaking changes compared to previous versions, so some examples/tutorials out there might not work without modification.
Here's a quick run-down of some cool stuff, maybe I can give you a few hints here myself which are clearly very brief and probably not great but hopefully gives you something to play with!:-
First note - most examples on the internet will assume 'lightweight syntax' is turned on. To achieve this use the following line of code:-
#light
This prevents you from having to insert certain keywords that are present for OCaml compatibility and also having to terminate each line with semicolons. Note that using this syntax means indentation defines scope. This will become clear in later examples, all of which rely on lightweight syntax being switched on.
If you're using the interactive mode you have to terminate all statements with double semi-colons, for example:-
> #light;;
> let f x y = x + y;;
val f : int -> int -> int
> f 1 2;;
val it : int = 3
Note that interactive mode returns a 'val' result after each line. This gives important information about the definitions we are making, for example 'val f : int -> int -> int' indicates that a function which takes two ints returns an int.
Note that only in interactive do we need to terminate lines with semi-colons, when actually defining F# code we are free of that :-)
You define functions using the 'let' keyword. This is probably the most important keyword in all of F# and you'll be using it a lot. For example:-
let sumStuff x y = x + y
let sumStuffTuple (x, y) = x + y
We can call these functions thus:-
sumStuff 1 2
3
sumStuffTuple (1, 2)
3
Note there are two different ways of defining functions here - you can either separate parameters by whitespace or specify parameters in 'tuples' (i.e. values in parentheses separated by commas). The difference is that we can use 'partial function application' to obtain functions which take less than the required parameters using the first approach, and not with the second. E.g.:-
let sumStuff1 = sumStuff 1
sumStuff 2
3
Note we are obtaining a function from the expression 'sumStuff 1'. When we can pass around functions just as easily as data that is referred to as the language having 'first class functions', this is a fundamental part of any functional language such as F#.
Pattern matching is pretty darn cool, it's basically like a switch statement on steroids (yeah I nicked that phrase from another F#-ist :-). You can do stuff like:-
let someThing x =
match x with
| 0 -> "zero"
| 1 -> "one"
| 2 -> "two"
| x when x < 0 -> "negative = " + x.ToString()
| _ when x%2 = 0 -> "greater than two but even"
| _ -> "greater than two but odd"
Note we use the '_' symbol when we want to match on something but the expression we are returning does not depend on the input.
We can abbreviate pattern matching using if, elif, and else statements as required:-
let negEvenOdd x = if x < 0 then "neg" elif x % 2 = 0 then "even" else "odd"
F# lists (which are implemented as linked lists underneath) can be manipulated thus:-
let l1 = [1;2;3]
l1.[0]
1
let l2 = [1 .. 10]
List.length l2
10
let squares = [for i in 1..10 -> i * i]
squares
[1; 4; 9; 16; 25; 36; 49; 64; 81; 100]
let square x = x * x;;
let squares2 = List.map square [1..10]
squares2
[1; 4; 9; 16; 25; 36; 49; 64; 81; 100]
let evenSquares = List.filter (fun x -> x % 2 = 0) squares
evenSqares
[4; 16; 36; 64; 100]
Note the List.map function 'maps' the square function on to the list from 1 to 10, i.e. applies the function to each element. List.filter 'filters' a list by only returning values in the list that pass the predicate function provided. Also note the 'fun x -> f' syntax - this is the F# lambda.
Note that throughout we have not defined any types - the F# compiler/interpreter 'infers' types, i.e. works out what you want from usage. For example:-
let f x = "hi " + x
Here the compiler/interpreter will determine x is a string since you're performing an operation which requires x to be a string. It also determines the return type will be string as well.
When there is ambiguity the compiler makes assumptions, for example:-
let f x y = x + y
Here x and y could be a number of types, but the compiler defaults to int. If you want to define types you can using type annotation:-
let f (x:string) y = x + y
Also note that we have had to enclose x:string in parentheses, we often have to do this to separate parts of a function definition.
Two really useful and heavily used operators in F# are the pipe forward and function composition operators |> and >> respectively.
We define |> thus:-
let (|>) x f = f x
Note that you can define operators in F#, this is pretty cool :-).
This allows you to write things in a clearer way, e.g.:-
[1..10] |> List.map (fun x -> x * x) |> List.filter (fun x -> x % 2 = 0)
Will allow you to obtain the first 10 even squares. That is clearer than:-
List.filter (fun x -> x % 2 = 0) (List.map (fun x -> x * x) [1..10])
Well, at least I think so :-)
Function composition defined by the >> operator is defined as follows:-
let (>>) f g x = g(f(x))
I.e. you forward-pipe an operation only the parameter of the first function remains unspecified. This is useful as you can do the following:-
let mapFilter = List.map (fun x -> x * x) >> List.filter (fun x -> x % 2 = 0)
Here mapFilter will accept a list an input and return the list filtered as before. It's an abbreviated version of:-
let mapFilter = l |> List.map (fun x -> x * x) |> List.filter (fun x -> x % 2 = 0)
If we want to write recursive functions we have to define the function as recursive by placing 'rec' after the let. Examples below.
Some cool stuff:-
Factorial
let rec fact x = if x <= 1 then 1 else x * fact (x-1)
nth Fibonacci Number
let rec fib n = if n <= 1 then n else fib (n-1) + fib (n-2)
FizzBuzz
let (/%) x y = x % y = 0
let fb = function
| x when x /% 15 -> "FizzBuzz"
| x when x /% 3 -> "Fizz"
| x when x /% 5 -> "Buzz"
| x -> x.ToString()
[1..100] |> List.map (fb >> printfn "%s")
Anyway that's a very brief overview, hopefully it helps a little!!
Without doubt, you should purchase Don Syme's excellent book "Expert F#". The book is very well written and is suitable for both beginners and experts alike. In it, you'll find both introductory material and much more challenging material too. At nearly 600 pages it is good value for money.
I found that it taught me a lot of useful techniques for writing more functional C# as well as providing all the reference material I needed to get started writing Windows hosted F# applications.
The book is published by Apress and has an accompanying web site at:
http://www.expert-fsharp.com/default.aspx
#kronoz - well thanks a lot for your long answer, that's a really good place to start from. I'll follow your advices, and look for the book #vecstasy mentioned.
now, let me go coding :-)
let thanksalot = "thanks a lot"
printfn "%s" (thanksalot);;
I've been reading Real World Functional Programming
With examples in F# and C# by:Tomas Petricek
So far I find it very good at teaching F# concepts by showing the implementations in C# on the side. Great for OO Programmers.
The first chapter of my book F# for Scientists is freely available here. We have a series of free F# toy programs here. The first article from our F#.NET Journal is freely available here.
Check out the F# Developer Center. There is also hubFS, a forum dedicated to F#.
If you have the current CTP release in Visual Studio it lets you create a F# Tutorial project, which gives you a Tutorial.fs, exactly containing what it's name suggests.
That tutorial also points to a larger collection of F# examples at Microsoft.
Also, there is an F# samples project going on at CodePlex.
Hope this helps,
Michiel