I have written two versions of code. The first one works as expected and print "Hi". the second one gives me error that "block following this let is unfinished"
1st version
#light
let samplefn() =
let z = 2
let z = z * 2
printfn "hi"
samplefn()
2nd version
#light
let samplefn() =
let z = 2
let z = z * 2
samplefn()
Only difference is the printfn is absent in the second version. I am using Visual Studio 2010 as my IDE. I am very new to F# but this error seems very strange to me. I guess I am missing some very important concept. Please explain.
Edit: Also if I do it outside the function I get error even with the first version of code.
#light
let z = 2
let z = z * 2
printfn "Error: Duplicate definition of value z"
let binds a value to a label but otherwise doesn't do much else. Your function contains two bindings but doesn't use them, and so you get an error.
To think of it another way, all functions in F# need a return value, which is the value of the last executed expression in your function. let doesn't have a return value so your function is invalid. To fix this you can add a return value, for example:
let samplefn() =
let z = 2
let z = z * 2
()
which defines a function that does absolutely nothing (returns unit). Perhaps a better example is this:
let samplefn() =
let z = 2
let z = z * 2
z
which will return 4 (the value of the binding for label z).
I think it is helpful to understand the non-light syntax here. Let's translate:
1st Version (let binding expressions)
let samplefn() =
let z = 2 in
let z = z * 2 in
printfn "hi";;
samplefn();;
The important thing to understand here is that all non-top-level let bindings are actually expressions of the form let <variable> = <expression1> in <expression2> where <variable> is bound to the result of <expression1> in a new scope <expression2>, and <expression2> is the return value of the entire expression. The light syntax makes you believe such let bindings are variable assignments / statements, when in fact it really is true that almost everything in F# is an expression.
Perhaps the following illustrates this more clearly:
let a = (let b = 3 in b + 2) //a is 5
2nd Version (top-level let bindings)
let z = 2;;
let z = z * 2;;
printfn "Error: Duplicate definition of value z";;
Top level let-bindings are terminated with ;;, indicating the completion of what may be thought of as a statement. The top-level is a single scope, and here we get an error for trying to bind z twice within the same scope. Whereas using the expression form of let bindings in Example 1, we bind z anew for each sub-scope in the expression chain. Note that we could do something like this at the top-level:
let z = (let z = 2 in z * 2);;
A let that is not at the top level (e.g. your indented ones) has to have a statement (actually an expression, as pst notes) called a "body" following the assignment. In the first example the body is printfn "hi", while the second example has no body. That's what the compiler is complaining about.
Note that in your function definitions the inner let expressions actually create nested scopes. That is, the let z = z * 2 actually creates a new value called z and binds to it the value of the outer z times 2, then uses it in the body of the let (which is the printfn in this case). A nested let will always have a body. It is the nesting which allows the seemingly duplicate definition.
Since an outermost let does not need a body, the compiler thinks you're trying to redefine z in the same scope, which is an error. You can use parentheses to tell the compiler how to properly interpret the last example:
let z = 2
(let z = z * 2
printfn "z = %d" z)
printfn "z = %d" z
The above will print z = 4
z = 2
Related
I want to create a function that check if the passed value is greater than zero.
The passed value can be an int or a decimal (ideally a "numeric value").
In the immediate I just started with this:
type number =
| I of int
| D of decimal
type Checker () =
member this.Validate value =
match value with
| I x when x > 0 -> "ok"
| D x when x > 0m -> "ok"
| _ -> "error"
let a = 1f
let b = 1m
//let a_IsValid = Checker().Validate(a) // does not compile, expect number (not int)
//let b_IsValid = Checker().Validate(b) // does not compile, expect number (not decimal)
Found not immediate to pass a "number" so tried something different...
I found this article (http://tomasp.net/blog/fsharp-generic-numeric.aspx/) and I thought
"static member constraint" is the perfect solution for me.
A basic example works as expected:
let inline divideByTwo value =
LanguagePrimitives.DivideByInt value 2
divideByTwo 1f |> ignore
divideByTwo 1m |> ignore
but a different scenario found me very surprised:
type Calculator () =
let divideByTwo value =
LanguagePrimitives.DivideByInt value 2
member this.DivideByTwo value =
LanguagePrimitives.DivideByInt value 2
member this.ValidateGeneric value =
match LanguagePrimitives.GenericGreaterThan value 0m with
| true -> "ok"
| _ -> "error"
//let half = Calculator().DivideByTwo(1) // DivideByInt does not support int !!
// cannot use both the following, the first one will "force" the type, and the other will not work
let a_half = Calculator().DivideByTwo(1f) // ok if used before the "decimal" version
let b_half = Calculator().DivideByTwo(1m) // ok only if comment the previous one
It seems not to work when I want to use more than one type for the passing value.
More than that, the function I need (GenericGreaterThan) seems to have another "limitation", explained below.
The example in the article use DivideByInt and, as the name said, it divide the passed value by an int, a well defined type.
LanguagePrimitives.GenericGreaterThan needs 2 parameters, a passed value and a fixed one to compare to. The signature of the function as only one generic type for both, so if you pass a type 'T it expect the second one to be 'T too.
I just wants to compare with zero without passing it, but using "0" forced my value
to be an int and using "0m" force the value to be a decimal.
There is a simple way to have a function that check if a "numeric" value is greater than "zero" ?
Should I use obj and box it .... or use cast ... or stop trying and just use a different function for every type I need ?
[UPDATE]
I tried to use the LanguagePrimitives.GenericZero as suggested but still not able to have a working solution for my particular scenario.
I created a new issue here: F# - Compare LanguagePrimitives.GenericZero with a value passed on the class contructor .
Comparing against zero generically is actually quite simple. The following function should work for any numeric type:
let inline isPositive x =
x > LanguagePrimitives.GenericZero
isPositive 1.0 |> printfn "%A" // true
isPositive 1m |> printfn "%A" // true
Dividing by two generically is also pretty easy. You just have to define your own generic two, since it's not a built-in primitive:
let inline divideByTwo x =
let two =
LanguagePrimitives.GenericOne
+ LanguagePrimitives.GenericOne
x / two
divideByTwo 5.0 |> printfn "%A" // 2.5
divideByTwo 4m |> printfn "%A" // 2
there lots of things here.
your first example didn't work because you needed to wrap your number inside the type number (I assume you realise this? but didnt want it to work like that?)
type Checker () =
member this.Validate value =
match value with
| I x when x > 0 -> "ok"
| D x when x > 0m -> "ok"
| _ -> "error"
let a = I 1
let b = D 1m
let a_IsValid = Checker().Validate(a)
let b_IsValid = Checker().Validate(b)
your second example is that in doesnt support divide by int?
yes what is the value of 1/2? its not an int, so thats correct by design.
the third question seems to be that this code doesnt compile and run?
type Calculator () =
member inline _.DivideByTwo value =
LanguagePrimitives.DivideByInt value 2
let b_half = Calculator().DivideByTwo(1m) // ok for me
let a_half = Calculator().DivideByTwo(1f) // ok for me
but this works for me.
The fourth question appears to be the need to use static constraints to test if something is > 0?
but 0 (as in mathematics) is a different thing in different number systems, its generic too so you need LanguagePrimitives.GenericZero. putting that all together we get
type Calculator () =
member inline _.DivideByTwo value =
LanguagePrimitives.DivideByInt value 2
member inline _.ValidateGeneric value =
match LanguagePrimitives.GenericGreaterThan
value
LanguagePrimitives.GenericZero with
| true -> "ok"
| _ -> "error"
let b_half = Calculator().DivideByTwo(1m)
let a_half = Calculator().DivideByTwo(1f)
let y = Calculator().ValidateGeneric(1m)
let z = Calculator().ValidateGeneric(1f)
as for the divide by 1/2 question, you may need to think what you want it to do? really the input type is defined by what output type you want? decimal? float? etc
i'm writing a small console application in F#.
[<EntryPoint>]
let main argv =
high_lvl_funcs.print_opt
let opt = Console.ReadLine()
match opt with
| "0" -> printfn "%A" (high_lvl_funcs.calculate_NDL)
| "1" -> printfn ("not implemented yet")
| _ -> printfn "%A is not an option" opt
from module high_lvl_funcs
let print_opt =
let options = [|"NDL"; "Deco"|]
printfn "Enter the number of the option you want"
Array.iteri (fun i x -> printfn "%A: %A" i x) options
let calculate_NDL =
printfn ("enter Depth in m")
let depth = lfuncs.m_to_absolute(float (Console.ReadLine()))
printfn ("enter amount of N2 in gas (assuming o2 is the rest)")
let fn2 = float (Console.ReadLine())
let table = lfuncs.read_table
let tissue = lfuncs.create_initialise_Tissues ATM WATERVAPOUR
lfuncs.calc_NDL depth fn2 table lfuncs.loading_constantpressure tissue 0.0
lfuncs.calc_NDL returns a float
this produces this
Enter the number of the option you want
0: "NDL"
1: "Deco"
enter Depth in m
which means it prints what it's suppose to then jumps straight to high_lvl_funcs.calculate_NDL
I wanted it to produce
Enter the number of the option you want
0: "NDL"
1: "Deco"
then let's assume 0 is entered, and then calculate high_lvl_funcs.calculate_NDL
after some thinking and searching i assume this is because F# wants to assign all values before it starts the rest. Then i thought that i need to declaring a variable without assigning it. but people seem to agree that this is bad in functional programming. From another question: Declaring a variable without assigning
so my question is, is it possible to rewrite the code such that i get the flow i want and avoid declaring variables without assigning them?
You can fix this by making calculate_NDL a function of no arguments, instead of a closure that evaluates to a float:
let calculate_NDL () =
Then call it as a function in your match like this:
match opt with
| "0" -> printfn "%A" (high_lvl_funcs.calculate_NDL())
However I'd suggest refactoring this code so that calculate_NDL takes any necessary inputs as arguments rather than reading them from the console i.e. read the inputs from the console separately and pass them to calculate_NDL.
let calculate_NDL depth fn2 =
let absDepth = lfuncs.m_to_absolute(depth)
let table = lfuncs.read_table
let tissue = lfuncs.create_initialise_Tissues ATM WATERVAPOUR
lfuncs.calc_NDL absDepth fn2 table lfuncs.loading_constantpressure tissue 0.0
It's generally a good idea to write as much code as possible as pure functions that don't rely on I/O (like reading from stdin).
Is there a way in F# to create a function that takes any other function as its sole parameter and return that function's body text as the result?
For example:
let myFunc =
// Always equals 3!
let x = 1 + 2
// Print it to the console
printfn "x = %i" x
let extractFunctionText f =
???
extractFunctionText myFunc
extractFunctionText should have a signature of ('a -> 'b) -> string i.e. it will take any function as an input and returns a string. The string I'd like returned in the last line of specific example above is:
"""// Always equals 3!
let x = 1 + 2
// Print it to the console
printfn "x = %i" x"""
Apologies for any typos or naive questions: I'm a bit of a newb at this. I think that following links (SO Answer & MSDN) get me quite close but I don't understand things well enough to finish the job
I am just getting started with F# and am trying Problem Euler problem #3. To find primes I came up with the following code to compute all primes up to a maximum number:
let rec allPrimes foundPrimes, current, max =
// make sure the current number isn't too high
// or the current number isn't divisible by any known primes
if current >= max then
foundPrimes
else
let nextValue = current + 1
if not List.exists (fun x -> current % x = 0L) foundPrimes then
allPrimes foundPrimes nextValue max
else
allPrimes (foundPrimes :: current) nextValue max
Unfortunately, this gives the error:
Only simple variable patterns can be bound in 'let rec' constructs
Why am I getting this error?
You don't want to put the commas in the declaration - change
let rec allPrimes foundPrimes, current, max =
to
let rec allPrimes foundPrimes current max =
The correct version of your original would be
let rec allPrimes (foundPrimes, current, max) =
note the brackets around the tuple. However, this would require modifying the recursive calls to also use tuple form. In the original version the compiler thinks you are trying to do something like
let a,b,c=1,2,3
which won't work for recursive functions.
Using an example from Chris Smith's Programming F# 3.0:
let invalidUseOfMutable() =
let mutable x = 0
let incrementX() = x <- x + 1
incrementX()
x;;
This fails as expected:
error FS0407: The mutable variable 'x' is used in an invalid way.
Mutable variables cannot be captured by closures.
Now cut and paste the body of the function into FSharp Interactive:
let mutable x = 0
let incrementX() = x <- x + 1
incrementX()
x;;
And it works!
val it : int = 1
Why?
Edit: the following answer is correct for F# up to 3.x. Starting with F# 4.0, local mutables are automatically converted into refs if needed, so OP's code will actually successfully compile in all cases.
Short answer: it's not because of fsi, it's because the mutable is global.
Long answer:
For a normal (non-mutable) capture, implementation-wise the captured value is copied into the function object, so that if you return this function and use it outside of the scope in which it has been defined, everything works fine.
let pureAddOne() =
let x = 1
let f y = x + y // the value 1 is copied into the function object
f
let g = pureAddOne()
g 3 // x is now out of scope, but its value has been copied and can be used
On the other hand, in order to capture a mutable, the capture needs to be done by reference, else you wouldn't be able to modify it. But this is impossible, because in the previously mentioned case where the closure is returned and used outside of its definition scope, the mutable is also out of scope and potentially deallocated. This is the reason for the initial limitation.
let mutableAddOne() =
let mutable x = 1
let f y = x <- x + y // x would be referenced, not copied
f
let g = mutableAddOne()
g 3 // x is now out of scope, so the reference is invalid!
// mutableAddOne doesn't compile, because if it did, then this would fail.
However, if the mutable is global, then there is no such scope issue, and the compiler accepts it. It's not just fsi; if you try to compile the following program with fsc, it works:
module Working
let mutable x = 1 // x is global, so it never goes out of scope
let mutableAddOne() =
let f y = x <- x + y // referencing a global. No problem!
f
let g = mutableAddOne()
g 3 // works as expected!
In conclusion, as kwingho said, if you want to have a closure that captures a local mutable value, use a ref. They are heap-allocated (as opposed to the stack-allocated local mutable) so as long as the closure holds a reference to it, it won't be deallocated.