Using Visual Studio 2015 Update 3 and fsi.exe from F# v4.0 I' trying to run this script:
//error.fsx
#if INTERACTIVE
let msg = "Interactive"
#else
let msg = "Not Interactive"
#endif
let add x y =
x + y
printfn "%d" (add 1 2)
Output: error.fsx(12,15): error FS0039: The value or constructor 'add' is not defined
If I then comment out the #if-#else-#endif block, it works fine:
// fixed.fsx
//#if INTERACTIVE
// let msg = "Interactive"
//#else
// let msg = "Not Interactive"
//#endif
let add x y =
x + y
printfn "%d" (add 1 2)
Output: 3
I'm sure I'm doing something wrong (rather than this being a bug) but I can't for the life of me figure out how to make this work.
Thoughts?
This is caused by the indentation of let msg. The following works fine:
#if INTERACTIVE
let msg = "Interactive"
#else
let msg = "Not Interactive"
#endif
let add x y =
x + y
printfn "%d" (add 1 2)
I do have to say, I'm not entirely sure why the code gives exactly the error message you mention - I suspect this is a bug in the error reporting and it wold be worth reporting it to the F# team. At the very least, there should be a sensible error message!
It seems that with the indentation, the F# parser actually parses the code as follows:
let msg = "Interactive"
let add x y =
x + y
printfn "%d" (add 1 2)
The spacing before let msg causes the compiler to treat printfn as being indented too. You can see that this is the case if you look at the type of the y variable in your editor using a tool tip...
Related
I am facing a problem that leave me disoriented, since it should be a pretty basic procedure. I am learning how to build simple console applications with F#, but I cannot figure out how to pass an integer as standard input to the program. Please consider:
open System
let square x = x * x
[<EntryPoint>]
let main (argv :string[]) =
printfn "The function will take an input and square it"
printfn "%d squared is %d" 12 (square 12)
Console.ReadLine() |> ignore
0
How can I pass the value to printfn and square the way I can do in C with:
int main(){
int i;
scanf("%d", &i);
printf("\nThe value of variable i is %d.\n", i);
return 0;
}
I tried to adapt let x = Console.ReadLine() to get integers, but no appreciable results. The documentation I consulted, mainly consider string inputs. I am afraid I am missing something important for properly comprehend the basic of F#. Any suggestion, in this sense, would be highly appreciated.
ReadLine () will return a string. As mentioned by #JohnPalmer, it needs to be parsed to an int. The following program should give you the basic idea:
let rec input () =
printf "Input: "
match Core.int.TryParse (stdin.ReadLine ()) with
| true, i -> i
| _ ->
printfn "Invalid input, try again"
input ()
let square x = x * x
[<EntryPoint>]
let main _ =
printfn "The function will take an input and square it"
let i = input ()
printfn "%d squared is %d" i (square i)
0
let make f =
printfn "1"
use file = File.CreateText("abc.txt")
let v = f file
printfn "2"
v
let f (x: StreamWriter) (y:int) =
printfn "3"
x.WriteLine("{0}", y)
let a = make f
> 1
> 2
> val a : (int -> unit)
a 8
System.ObjectDisposedException: The object was used after being disposed.
When compiling this doesn't give me any error or warning, but in the runtime it triggers such error.
Do I have to use the full version let make f y = ... to avoid the curried form?
The use keyword ensures that the Dispose method is called at the end of the lexical scope. This means that it calls it when a value is returned from your make function. The problem is that in your case, the returned value is a function that is called later.
In other words, what you're writing could be also seen as:
let make f =
printfn "1"
use file = File.CreateText("abc.txt")
printfn "2"
(fun y -> f file y)
Here, you can see why this does not work. If you want to call the function f with all arguments before the file is disposed of, you need to write something like this:
let make f y =
printfn "1"
use file = File.CreateText("abc.txt")
let v = f file y
printfn "2"
v
F# allows to use checked arithmetics by opening Checked module, which redefines standard operators to be checked operators, for example:
open Checked
let x = 1 + System.Int32.MaxValue // overflow
will result arithmetic overflow exception.
But what if I want to use checked arithmetics in some small scope, like C# allows with keyword checked:
int x = 1 + int.MaxValue; // ok
int y = checked { 1 + int.MaxValue }; // overflow
How can I control the scope of operators redefinition by opening Checked module or make it smaller as possible?
You can always define a separate operator, or use shadowing, or use parens to create an inner scope for temporary shadowing:
let f() =
// define a separate operator
let (+.) x y = Checked.(+) x y
try
let x = 1 +. System.Int32.MaxValue
printfn "ran ok"
with e ->
printfn "exception"
try
let x = 1 + System.Int32.MaxValue
printfn "ran ok"
with e ->
printfn "exception"
// shadow (+)
let (+) x y = Checked.(+) x y
try
let x = 1 + System.Int32.MaxValue
printfn "ran ok"
with e ->
printfn "exception"
// shadow it back again
let (+) x y = Operators.(+) x y
try
let x = 1 + System.Int32.MaxValue
printfn "ran ok"
with e ->
printfn "exception"
// use parens to create a scope
(
// shadow inside
let (+) x y = Checked.(+) x y
try
let x = 1 + System.Int32.MaxValue
printfn "ran ok"
with e ->
printfn "exception"
)
// shadowing scope expires
try
let x = 1 + System.Int32.MaxValue
printfn "ran ok"
with e ->
printfn "exception"
f()
// output:
// exception
// ran ok
// exception
// ran ok
// exception
// ran ok
Finally, see also the --checked+ compiler option:
http://msdn.microsoft.com/en-us/library/dd233171(VS.100).aspx
Here is a complicated (but maybe interesting) alternative. If you're writing something serious then you should probably use one of the Brians suggestions, but just out of curiosity, I was wondering if it was possible to write F# computation expression to do this. You can declare a type that represents int which should be used only with checked operations:
type CheckedInt = Ch of int with
static member (+) (Ch a, Ch b) = Checked.(+) a b
static member (*) (Ch a, Ch b) = Checked.(*) a b
static member (+) (Ch a, b) = Checked.(+) a b
static member (*) (Ch a, b) = Checked.(*) a b
Then you can define a computation expression builder (this isn't really a monad at all, because the types of operations are completely non-standard):
type CheckedBuilder() =
member x.Bind(v, f) = f (Ch v)
member x.Return(Ch v) = v
let checked = new CheckedBuilder()
When you call 'bind' it will automatically wrap the given integer value into an integer that should be used with checked operations, so the rest of the code will use checked + and * operators declared as members. You end up with something like this:
checked { let! a = 10000
let! b = a * 10000
let! c = b * 21
let! d = c + 47483648 // !
return d }
This throws an exception because it overflows on the marked line. If you change the number, it will return an int value (because the Return member unwraps the numeric value from the Checked type). This is a bit crazy technique :-) but I thought it may be interesting!
(Note checked is a keyword reserved for future use, so you may prefer choosing another name)
I'd like to create a builder that builds expressions that returns something like a continuation after each step.
Something like this:
module TwoSteps =
let x = stepwise {
let! y = "foo"
printfn "got: %A" y
let! z = y + "bar"
printfn "got: %A" z
return z
}
printfn "two steps"
let a = x()
printfn "something inbetween"
let b = a()
Where the 'let a' line returns something containing the rest of the expressions to be evaluated later on.
Doing this with a separate type for each number of steps is straightforward but of course not particularly useful:
type Stepwise() =
let bnd (v: 'a) rest = fun () -> rest v
let rtn v = fun () -> Some v
member x.Bind(v, rest) =
bnd v rest
member x.Return v = rtn v
let stepwise = Stepwise()
module TwoSteps =
let x = stepwise {
let! y = "foo"
printfn "got: %A" y
let! z = y + "bar"
printfn "got: %A" z
return z
}
printfn "two steps"
let a = x()
printfn "something inbetween"
let b = a()
module ThreeSteps =
let x = stepwise {
let! y = "foo"
printfn "got: %A" y
let! z = y + "bar"
printfn "got: %A" z
let! z' = z + "third"
printfn "got: %A" z'
return z
}
printfn "three steps"
let a = x()
printfn "something inbetween"
let b = a()
printfn "something inbetween"
let c = b()
And the results are what I'm looking for:
two steps
got: "foo"
something inbetween
got: "foobar"
three steps
got: "foo"
something inbetween
got: "foobar"
something inbetween
got: "foobarthird"
But I can't figure out what the general case of this would be.
What I'd like is to be able to feed events into this workflow, so you could write something like:
let someHandler = Stepwise<someMergedEventStream>() {
let! touchLocation = swallowEverythingUntilYouGetATouch()
startSomeSound()
let! nextTouchLocation = swallowEverythingUntilYouGetATouch()
stopSomeSound()
}
And have events trigger a move to the next step in the workflow. (In particular, I want to play with this sort of thing in MonoTouch - F# on the iPhone. Passing around objc selectors drives me insane.)
the problem with your implementation is that it returns "unit -> 'a" for each call to Bind, so you'll get a different type of result for different number of steps (in general, this is a suspicious definition of monad/computation expression).
A correct solution should be to use some other type, which can represent a computation with arbitrary number of steps. You'll also need to distinguish between two types of steps - some steps just evaluate next step of the computation and some steps return a result (via the return keyword). I'll use a type seq<option<'a>>. This is a lazy sequence, so reading the next element will evaluate the next step of the computation. The sequence will contain None values with the exception of the last value, which will be Some(value), representing the result returned using return.
Another suspicious thing in your implementation is a non-standard type of Bind member. The fact that your bind takes a value as the first parameter means that your code looks a bit simpler (you can write let! a = 1) however, you cannot compose stepwise computation. You may want to be able to write:
let foo() = stepwise {
return 1; }
let bar() = stepwise {
let! a = foo()
return a + 10 }
The type I described above will allow you to write this as well. Once you have the type, you just need to follow the type signature of Bind and Return in the implementation and you'll get this:
type Stepwise() =
member x.Bind(v:seq<option<_>>, rest:(_ -> seq<option<_>>)) = seq {
let en = v.GetEnumerator()
let nextVal() =
if en.MoveNext() then en.Current
else failwith "Unexpected end!"
let last = ref (nextVal())
while Option.isNone !last do
// yield None for each step of the source 'stepwise' computation
yield None
last := next()
// yield one more None for this step
yield None
// run the rest of the computation
yield! rest (Option.get !last) }
member x.Return v = seq {
// single-step computation that yields the result
yield Some(v) }
let stepwise = Stepwise()
// simple function for creating single-step computations
let one v = stepwise.Return(v)
Now, let's look at using the type:
let oneStep = stepwise {
// NOTE: we need to explicitly create single-step
// computations when we call the let! binder
let! y = one( "foo" )
printfn "got: %A" y
return y + "bar" }
let threeSteps = stepwise {
let! x = oneStep // compose computations :-)
printfn "got: %A" x
let! y = one( x + "third" )
printfn "got: %A" y
return "returning " + y }
If you want to run the computation step-by-step, you can simply iterate over the returned sequence, for example using the F# for keyword. The following also prints the index of the step:
for step, idx in Seq.zip threeSteps [ 1 .. 10] do
printf "STEP %d: " idx
match step with
| None _ -> ()
| Some(v) -> printfn "Final result: %s" v
Hope this helps!
PS: I found this problem very interesting! Would you mind if I addapted my answer into a blog post for my blog (http://tomasp.net/blog)? Thanks!
Monads and computation builders confuse the hell out of me, but I've adapted something I've made in an earlier SO post. Maybe some bits and pieces can be of use.
The code below contains an action queue, and a form where the Click event listens to the next action available in the action queue. The code below is an example with 4 actions in succession. Execute it in FSI and start clicking the form.
open System.Collections.Generic
open System.Windows.Forms
type ActionQueue(actions: (System.EventArgs -> unit) list) =
let actions = new Queue<System.EventArgs -> unit>(actions) //'a contains event properties
with
member hq.Add(action: System.EventArgs -> unit) =
actions.Enqueue(action)
member hq.NextAction =
if actions.Count=0
then fun _ -> ()
else actions.Dequeue()
//test code
let frm = new System.Windows.Forms.Form()
let myActions = [
fun (e:System.EventArgs) -> printfn "You clicked with %A" (e :?> MouseEventArgs).Button
fun _ -> printfn "Stop clicking me!!"
fun _ -> printfn "I mean it!"
fun _ -> printfn "I'll stop talking to you now."
]
let aq = new ActionQueue(myActions)
frm.Click.Add(fun e -> aq.NextAction e)
//frm.Click now executes the 4 actions in myActions in order and then does nothing on further clicks
frm.Show()
You can click the form 4 times and then nothing happens with further clicks.
Now execute the following code, and the form will respond two more times:
let moreActions = [
fun _ -> printfn "Ok, I'll talk to you again. Just don't click anymore, ever!"
fun _ -> printfn "That's it. I'm done with you."
]
moreActions |> List.iter (aq.Add)
I'm using F# v 1.9.6.2, and I've defined a very simple computation expression:
type MaybeBuilder() =
member this.Let(x, f) =
printfn "this.Let: %A" x
this.Bind(Some x, f)
member this.Bind(x, f) =
printfn "this.Bind: %A" x
match x with
| Some(x) when x >= 0 && x <= 100 -> f(x)
| _ -> None
member this.Delay(f) = f()
member this.Return(x) = Some x
let maybe = MaybeBuilder()
I've sprinkled some print statements in the code to tell me which methods are being called in a computation expression. When I execute the following statement:
maybe {
let x = 12
let! y = Some 11
let! z = Some 30
return x + y + z
}
I expect the console to print out the following:
this.Let 12
this.Bind Some 12
this.Bind Some 11
this.Bind Some 30
But my actual results are as follows:
this.Bind: Some 11
this.Bind: Some 30
In other words, F# doesn't appear to be executing the Let member. When I re-write Let to throw an exception, the code run without an exception. Additionally, when I comment out the Let member entirely, I do not get an error message stating The field, constructor or member 'Let' is not defined, and the code executes as expected.
(I've tried investigating the code with Reflector, but as is usually the case, decompiled F# is mangled beyond readability.)
It looks like the spec for computation expressions has changed. Are let bindings no longer treated as syntax sugar, and is the Let members no longer required in computation workflows?
You had the answer yourself. From the F# spec that describes how computation expressions are translated:
{| let binds in cexpr |}C = let binds in {| cexpr |}C)
So no, you don't need to define let explicitly anymore, it's translated by the compiler.
Update: this change is mentioned in the detailed release notes of the September CTP.
Correct -- you can no longer provide a binding for let :(.
See also
http://cs.hubfs.net/forums/thread/6950.aspx