Is it possible to pass a reference to a function to another function in F#? Specifically, I'd like to pass lambda functions like
foo(fun x -> x ** 3)
More specifically, I need to know how I would refer to the passed function in a function that I wrote myself.
Yes, it is possible. The manual has this example:
> List.map (fun x -> x % 2 = 0) [1 .. 5];;
val it : bool list
= [false; true; false; true; false]
Functions are first class citizens in F#. You can therefore pass them around just like you want to.
If you have a function like this:
let myFunction f =
f 1 2 3
and f is function then the return value of myFunction is f applied to 1,2 and 3.
Passing a lambda function to another function works like this:
Suppose we have a trivial function of our own as follows:
let functionThatTakesaFunctionAndAList f l = List.map f l
Now you can pass a lambda function and a list to it:
functionThatTakesaFunctionAndAList (fun x -> x ** 3.0) [1.0;2.0;3.0]
Inside our own function functionThatTakesaFunctionAndAList you can just refer to the lambda function as f because you called your first parameter f.
The result of the function call is of course:
float list = [1.0; 8.0; 27.0]
Related
I would like to write a function which takes several tupples as arguments and choose theirs ith elements and passes to another function, where i is given as another argument. I've tried sth like this:
let function (tup1:'A*'A) (tup2:'B*'B) i =
otherFunction (i tup1) (i tup2)
function Tup1 Tup2 fst
I've got an error, because i was expected to be 'A*'A ->'A not 'B*'B->'B.
Is it any way to make this code to work?
Thanks in advance.
You basically want to pass an argument of type ∀'a.'a*'a->'a, but in F# (and other MLs), only rank-1 polymorphism is supported so you can't do this directly. The workaround is to define a new type with a generic method to emulate higher-rank polymorphism:
type Untupler =
abstract Apply : 'a*'a -> 'a
let myFunction tup1 tup2 (i:Untupler) =
otherFunction (i.Apply tup1) (i.Apply tup2)
myFunction Tup1 Tup2 { new Untupler with member __.Apply (x,y) = x }
When you use the function i with tup1, it's inferred to be of the type 'A * 'A -> 'A. This means that when you use it with tup2, the only way that can work is if tup2 is also an 'A * 'A.
The function i can't change type within the same function. If there's a way to do what you want, I'm not aware of it, but you can sidestep the issue like this:
let myFunction x y =
otherFunction x y
Call it like this:
myFunction (fst tup1) (fst tup2)
This puts slightly more responsibility of the caller, but the advantage is that it's possible :)
Is it possible to pass a F# function by Reflection?
(*in module A*)
type Foo() =
static member bar n = {1..n}
let functionUsingFoobar (x:(int -> #('a seq)) n =
let z = BarFoo.ofSeq (x n)
z.count
(* in module B
here is where I want to pass Foo.bar by reflection*)
let y = functionUsingFoobar Foo.bar 1000
I cannot invoke the member without the args parameter, so partial function application through InvokeMember cannot work.
let foo = new Foo()
let z = foo.GetType().InvokeMember("bar", System.Reflection.BindingFlags.InvokeMethod, null, foo, [|1000|])
(*tried null, [||], [|null|] for args parameter*)
I'm out of ideas how to pass the function by reflection
The problem is that GetMethod returns a MethodInfo, but you need an F# function value. The easiest way to overcome this mismatch is probably to use CreateDelegate to create a .NET delegate from the method, and then treat the Invoke method as a function value of the correct type:
let d =
typeof<Foo>.GetMethod("bar").CreateDelegate(typeof<System.Func<int,seq<int>>>)
:?> System.Func<int,seq<int>>
functionUsingFooBar d.Invoke 1000
If this is what I think you want, it works just fine
type Foo() =
static member bar n = {1..n}
let functionUsingFoobar (x:(int -> #('a seq))) n =
(x n) |> Seq.length
let y = functionUsingFoobar Foo.bar 1000
let foo = new Foo()
let z = fun t -> foo.GetType().InvokeMember("bar", System.Reflection.BindingFlags.InvokeMethod, null, foo, [|t|])
Say I have a recursive function that I want to know how many times the function has called itself per input value. Rather than putting printf expressions or changing the return type to include the number of calls, is it possible to "wrap" the function with another to achive this? I would like the wrapped function to return the number of function calls and the original functions result. It should be reusable across different functions.
Here is what I have and it doesn't work.
open System
open System.IO
open System.Collections.Generic
/// example recursive function
let rec getfilenames dir =
seq {
yield Directory.GetFiles dir
for x in Directory.GetDirectories dir do yield! getfilenames x}
/// function to count the number of calls a recursive function makes to itself
let wrapped (f: 'a -> 'b) =
let d = new Dictionary<'a, int>()
fun x ->
let ok, res = d.TryGetValue(x)
if ok then d.[x] <- d.[x] + 1
else
d.Add(x, 1)
d, f x
> let f = wrapped getfilenames
let calls, res = f "c:\\temp";;
val f : (string -> Dictionary<string,int> * seq<string []>)
val res : seq<string []>
val calls : Dictionary<string,int> = dict [("c:\temp", 1)]
This is not going to work, because getfilenames is defined as calling getfilenames, not any other function and especially not a function defined after that. So, as soon as your wrapper calls the function, the function will ignore your wrapper and start calling itself.
What you need to do is move the recursion out of the getfilenames function and into another function, by providing the function to be called recursively as a parameter.
let body recfun dir =
seq {
yield Directory.GetFiles dir
for x in Directory.GetDirectories dir do yield! recfun x}
let rec getfilenames dir = body getfilenames dir
Now, you can wrap body before plugging it into a recursive function:
let wrap f =
let d = (* ... *) in
d, fun recfun x ->
let ok, res = d.TryGetValue(x)
if ok then d.[x] <- d.[x] + 1
else d.Add(x, 1)
f recfun x
let calls, counted_body = wrap body
let getfilenames dir = counted_body getfilenames dir
Note that the wrap function returns both the wrapped function (with a signature identical to the original function) and the dictionary, for external access. The number of calls will then be found in calls.
As Victor points out, you cannot take a recursive function and "inject" some behavior into the place where the recursive call happens (because the function is already complete). You'll need to provide some extension point for that. In Victor's solution, this is done by taking a function to be called recursively as an argument, which is the most general solution.
A simpler option is to use F# value recursion which allows you to create a function value and use it in its declaration. You can use this to create a recursive function by calling another function that adds some behavior to the function (e.g. counting):
let rec factorial = counted (fun x ->
if x = 0 then 1
else x * (factorial (x - 1)) )
factorial 10
Inside the lambda function, we can directly access the function we're defining, so there is no need for passing function to be called recursively as additional parameter. The function counted simply wraps the given function f and adds some functionality:
let counted f =
let count = ref 0
(fun x ->
count := !count + 1;
printfn "call: %d" (!count)
f x)
Thanks to the value recursion, the functionality will be added to the factorial function (and so when it calls itself, it will call the version with added counting support).
Is it possible to write a function to accept a tuple of variable length? I'm trying to write a method that can be called like this:
let a = sum(1,2)
let b = sum(1,2,3)
EDIT: Could it be interpreted as a function call with params? Or would the method need to be written in c#:
double sum(params object[] double) {
...
}
No - tuples are by definition not variable length, and to write a function like this you'd need something like template metaprogramming in C++ - and there isn't such a thing in F#; let inline won't help you there either.
Of course, if you take a list instead, it won't look that much different:
sum[1; 2]
sum[1; 2; 3]
#PavelMineav is right, you can't do it, but note that members can be overloaded, a la
type Foo() =
member this.sum(x,y) = x + y
member this.sum(x,y,z) = x + y + z
let foo = new Foo()
printfn "%d" (foo.sum(1,2))
printfn "%d" (foo.sum(1,2,3))
whereas let-bound functions cannot.
C# has anonymous delegates. So I can write:
public vois foo(string d, Action t){
t();
}
In ruby:
def foo d
yield
end
How to do the same in F#? Prefered syntax is:
foo "dfdfdf" { do something here }
Thanks
Your first example isn't an anonymous method -- it's just passing and calling through a delegate (which might refer to a named or an anonymous method). To do this in F#, just provide and call a function argument:
let foo n f = f n
let square n = n * n
let result = foo 123 square
printfn "%A" result
To create the equivalent of an anonymous method in F#, use the fun keyword:
let result2 = foo 123 (fun n -> n * n)
Have a look at this article about Higher Order Functions in F#. Higher Order Functions are functions which accept other functions as arguments, and sound like the concept you are describing.
open System
// create a function that expects an Action delegate and executes it
let foo (actionDelegate:Action) (s:String) = actionDelegate.Invoke();
// create a function that meets Action delegate
let ActionFunction param = Console.Write("Action in action")
// call foo passing ActionFunction
foo (new Action(ActionFunction)) "my string"