Reputation: 89
I've started a course on introduction to F#, and I've been having some trouble with two assignments. The first one had me creating two functions, where the first function takes an input and adds it with four, and the second one calculates sqrt(x^2+y^2). Then I should write function expressions for them both, but for some reason it gives me the error "Unexpected symbol'|' in implementation file".
let g = fun n -> n + 4;;
let h = fun (x,y) -> System.Math.Sqrt((x*x)+(y*y));;
let f = fun (x,n) -> float
|(n,0) -> g(n)
|(x,n) -> h(x,n);;
The second assignment asks me to create a function, which finds the sequence of Fibonaccis numbers. I've written the following code, but it seems to forget about the 0 in the beginning since the output always is n+1 and not n.
let rec fib = function
|0 -> 0
|1 -> 1
|n -> fib(n-1) + fib(n-2)
;;
Keep in mind that this is the first week, so I should be able to create these with those methods.
Upvotes: 1
Views: 195
Reputation: 36708
I'm going to address your first block of code, and leave the Fibonacci function for later. First I'll repost your code, then I'll talk about it.
let g = fun n -> n + 4;;
let h = fun (x,y) -> System.Math.Sqrt((x*x)+(y*y));;
let f = fun (x,n) -> float
|(n,0) -> g(n)
|(x,n) -> h(x,n);;
First comment: If you're defining a function and assigning it immediately to a name, like in all these examples, you don't need the fun
keyword. The usual way to define functions is to write them as let (name) (parameters) = (function body)
. So your code above would become:
let g n = n + 4;;
let h (x,y) = System.Math.Sqrt((x*x)+(y*y));;
let f (x,n) = float
|(n,0) -> g(n)
|(x,n) -> h(x,n);;
I haven't made any other changes, so your f
function still has an error in it. Let's address that error next.
I think the mistake you're making here is to think that fun
and function
are interchangeable. They're not. fun
is standard function definition, but function
is something else. It's a very common pattern in F# to write functions like the following:
let someFunc parameter =
match parameter with
| "case 1" -> printfn "Do something"
| "case 2" -> printfn "Do something else"
| _ -> printfn "Default behavior"
The function
keyword is shorthand for one parameter plus a match expression. In other words, this:
let someFunc = function
| "case 1" -> printfn "Do something"
| "case 2" -> printfn "Do something else"
| _ -> printfn "Default behavior"
is exactly the same code as this:
let someFunc parameter =
match parameter with
| "case 1" -> printfn "Do something"
| "case 2" -> printfn "Do something else"
| _ -> printfn "Default behavior"
with just one difference. In the version with the function
keyword, you don't get to pick the name of the parameter. It gets automatically created by the F# compiler, and since you can't know in advance what the name of the parameter will be, you can't refer to it in your code. (Well, there are ways, but I don't want to make you learn to run before you have learned to walk, so to speak). And one more thing: while you're still learning F#, I strongly recommend that you do NOT use the function
keyword. It's really useful once you know what you're doing, but in your early learning stages you should use the more explicit match (parameter) with
expressions. That way you'll get used to seeing what it's doing. Once you've been doing F# for a few months, then you can start replacing those let f param = match param with (...)
expressions with the shorter let f = function (...)
. But until match param with (...)
has really sunk in and you've understood it, you should continue to type it out explicitly.
So your f
function should have looked like:
let f (x,n) =
match (x,n) with
|(n,0) -> g(n)
|(x,n) -> h(x,n);;
I see that while I was typing this, Tomas Petricek posted a response, and it addresses the incorrect usage of float
, so I won't duplicate his explanation of why you're going to get an error on the word float
in your f
function. And he also explained about ;;
, so I won't duplicate that either. I'll just say that when he mentions "any decent editor with command for sending code to F# interactive (via Alt+Enter)", there are a lot of editor choices -- but as a beginner, you might just want someone to recommend one to you, so I'll recommend one. First off, though: if you're on Windows, you might be using Visual Studio already, in which case you should stick to Visual Studio since you know it. It's a good editor for F#. But if you don't use Visual Studio yet, I don't recommend downloading it just to play around with F#. It's a beast of a program, designed for professional software developers to do all sorts of things they need to do in their jobs, and so it can feel a bit overwhelming if you're just getting started. So I would actually recommend something more lightweight: the editor called Visual Studio Code. It's cross-platform, and will run perfectly well on Linux, OS X or on Windows. Once you've downloaded and installed VS Code, you'll then want to install the Ionide extension. Ionide is a plugin for VS Code (and also for Atom, though the Atom version of Ionide is updated less often since all the Ionide developers use VS Code now) that makes F# editing a real pleasure. There are actually three extensions you'll find: Ionide-fsharp, Ionide-FAKE, and Ionide-Paket. Download and install all three: FAKE and Paket are two tools for F# programming that you might not need yet, but once you do need them, you'll already have them installed.
Okay, that's enough to get you started, I think.
Upvotes: 3
Reputation: 243096
Your first snippet mostly suffers from two issues:
In F#, there is a difference between float
and int
. You write integer values as 4
or 0
and you write float values as 4.0
or 0.0
. F# does not automatically convert integers to floats, so you need to be consistent.
Your syntax in the f
function is a bit odd - I'm not sure what float
is supposed to mean there and the fun
and function
constructs behave differently.
So, starting with your original code:
let g = fun n -> n + 4;;
This works, but I would not write it as an explicit function using fun
- you can use let
to define functions too and it is simpler. Also, you only need ;;
in F# Interactive, but if you're using any decent editor with command for sending code to F# interactive (via Alt+Enter) you do not need that.
However, in your f
function, you want to return float
so you need to modify g
to return float too. This means replacing 4
with 4.0
:
let g n = n + 4.0
The h
function is good, but you can again write it using let
:
let h (x,y) = System.Math.Sqrt((x*x)+(y*y));;
In your f
function, you can either use function
to write a function using pattern matching, or you can use more verbose syntax using match
(function
is just a shorthand for writing a function and then pattern matching on the input):
let f = function
| (n,0.0) -> g(n)
| (x,n) -> h(x,n)
let f (x, y) =
match (x, y) with
| (n,0.0) -> g(n)
| (x,n) -> h(x,n)
Also note that the indentation matters - you need spaces before |
.
Upvotes: 5