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
Related
using the lib 'FsToolkit.ErrorHandling'
and the following code:
let f x =
if x % 2 = 0 then Ok $"even {x}" else Error $"odd {x}"
let xx =
validation {
let! a = f 1
and! b = f 2
and! c = f 3
return $"{a} {b} {c}"
}
printfn $"{xx.GetType()}"
The output is a
Result<string, string list>
Or, more specifically:
Microsoft.FSharp.Core.FSharpResult2[System.String,Microsoft.FSharp.Collections.FSharpList1[System.String]]
But the IDE (Rider) sees it differently:
Is this an expected behavior for some reason? or could it be a bug?
Validation<'a, 'err> is a type alias for Result<'a, 'err list>:
https://github.com/demystifyfp/FsToolkit.ErrorHandling/blob/f5019f10c4418426a2e182377be06beecd09876b/src/FsToolkit.ErrorHandling/Validation.fs#L3
This doesn't create a new type but creates a new way to refer to an existing type, which means that they can be used interchangeably.
in F#, it's not allowed to have mutable argument with functions. but if I have a function like the following:
let f x =
while x>0 do
printfn "%d" x
x <- x-1;;
when I compile this, I'm getting a compiler error.(not mutable)
How would I fix this function?
For pass-by-value semantics, you can use parameter shadowing.
Here, a shadowed (because it's the same name) mutable value x is declared on the stack.
let f x =
let mutable x = x
while x > 0 do
printfn "%d" x
x <- x - 1
For pass-by-reference semantics, you'll have to use a reference cell, which is a just a fancy way of passing an object which has a mutable field in it. It's similar to ref in C#:
let f x =
while !x > 0 do
printfn "%d" !x
x := !x - 1
Using a reference cell:
let x = (ref 10)
f x
Debug.Assert(!x = 0)
You could rewrite it like this:
let f x = [x.. -1..1] |> List.iter (printfn "%d")
If you want to keep the while loop, you could do this:
let f (x : byref<int>)=
while x>0 do
printfn "%d" x
x <- x-1
let mutable x = 5
f &x
Depends on whether you want the final, mutated value of x to be passed back to the caller of the function or mutate it only locally.
For local-only mutation, just declare another variable, which would be mutable, but initially will have the value of x:
let f x =
let mutable i = x
while i>0 do
printfn "%d" i
i <- i-1
For passing the result back to the caller, you can use a ref-cell:
let f (x: int ref) =
while x.Value>0 do
printfn "%d" x.Value
x := x.Value - 1
Note that now you have to refer to the ref-cell contents via the .Value property (or you can instead use operator !, as in x := !x - 1), and the mutation is now done via :=. Plus, the consumer of such function now has to create a ref-cell before passing it in:
let x = ref 5
f x
printfn "%d" x.Value // prints "0"
Having said that, I must point out that mutation is generally less reliable, more error-prone than pure values. The normal way to write "loops" in pure functional programming is via recursion:
let rec f x =
if x > 0 then
printf "%d" x
f (x-1)
Here, each call to f makes another call to f with the value of x decreased by 1. This will have the same effect as the loop, but now there is no mutation, which means easier debugging and testing.
In F# I can define an add1 function
let add1 x = x + 1
I can then define an add2 as the add1 function called on itself
let add2 x = add1 (add1 x)
Or by composing the add1 function with itself
let add2 = add1 >> add1
I was trying to implement the lambda calculus combinators in F#, the first being Identity
let I x = x
I then tried to define the Identity of Identity
let II = I >> I
But this caused the following compilation error:
Value restriction. The value 'II' has been inferred to have generic
type
val II : ('_a -> '_a) Either make the arguments to 'II' explicit or, if you do not intend for it to be generic, add a type
annotation
I can however define it as
let II x = I (I x)
I'm new to F# and am curious why?
This error has nothing to do with function composition itself, it's about Value Restriction. It happens because F# compiler infers types as generic as possible, but although it can easily generalize function, it can't generalize value (even though your value is in fact a function).
This answer can help you avoid this problems, but basically you should specify an input parameter:
let II x = (I>>I) x
or
let II x = I >> I <| x
#kagetogi is right.
The F# compiler wants to resolve values into concrete types and it will try to do so as soon as you use the function the first time. So this fails:
let I x = x
let II = I >> I
But this works:
let I x = x
let II = I >> I
II 5 |> printfn "%A"
Here II has type int->int. Which means that the following fails:
let I x = x
let II = I >> I
II 5 |> printfn "%A"
II 5.0 |> printfn "%A"
Because the second call is expecting an int not a float.
That is why in F# the pipe |> operator is preferred over the composition operator >>.
let I x = x
let II x = x |> I |> I
let II' x = x |> (I >> I)
Now finally II has generic type 'a->'a.
They both achieve function composition in the end.
Adding the code annotation also works:
let II<'a> : 'a->'a = I >> I
I am looking for a way to fix this very certain situation: I have a function-factory toF that takes a function-parameter g and based on it creates a resulting function f
let toF g =
let f x = g x
f
let f = toF id
The problem is that I get a
error FS0030: Value restriction. The value 'f' has been inferred to have generic type val f : ('_a -> '_a) Either make the arguments to 'f' explicit or, if you do not intend for it to be generic, add a type annotation.
I can add type annotations (which I am not eager to do) or alternatively I can rewrite it like this:
let f' g x = g x
let f x = f' id x
I don't like doing it this way because if I do then every time I call f I am making another call to f' specifying g along the way. While the first example keeps g in the closure and requires just one call.
UPDATE (for Tomas)
I have tried what you suggested.
let toF g =
printfn "Creating f using g"
let f x =
printfn "x: %A" x
g x
f
let f x = toF id x
let ``test``() =
1 |> f |> f |> ignore
What basically is happening is that every time I make a call to the function f it first calls toF id getting a composed function and only then calls that composed function on x.
Creating f using g
x: 1
Creating f using g
x: 1
So essentially the composition is created on every call to f via subsequent call to toF. But this is exactly what I was trying to avoid. By defining let f = toF id I was hoping to get a closure one sigle time and then be able to call it immediately. So the output I am expecting would be:
Creating f using g
x: 1
x: 1
UPDATE 2
The following doesn't work either for the very same reason:
let toF g =
printfn "Creating f using g"
let f x =
printfn "x: %A" x
g x
f
let f() = toF id
let fg = f()
You just need to make f a syntactic function:
let toF g =
let f x = g x
f
let f x = toF id x
When f is not syntactically a function (taking parameter) but a value, you hit the "value restriction" error. I'm not going to try to explain it here, because there is already great info in previous posts like: Understanding F# Value Restriction Errors.
EDIT - If you want to make sure that g gets called only once (but still want the code to be generic) then the easiest way is to add unused unit parameter (to make it a function) and then call it once (which determines the generic parameters) and use the result multiple times:
let toF g =
let f x = g x
f
let f () = toF id
let fg = f ()
fg 1
fg 2
This is sadly needed, because having a function that is generic, but is returned by some computation would actually create a subtle hole in the type system - that's the reason for the "value restriction".
The easiest solution is to just add a type annotation. Assuming that there's only one real type you care about, this is completely straightforward:
let toF g =
let f x = g x
f
let f : _ -> int = toF id
If you really need to call f at different types, then you can wrap it in a generic type:
type F<'t>() =
static member val f : _ -> 't = toF id
let blah = F.f "blah"
let one = F.f 1
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)