Is this possible in F# with Alea GPU?
Declare a function:
let my_function = fun a b -> a + b
Pass the kernel that function, and use it within the kernel:
let result = my_function 5 9
I understand that an alternative is to simply statically declare the function like:
[<ReflectedDefinition>]
let my_function a b =
a + b
But I want to be able to change my_function based on the parameters of the program.
For example:
[<ReflectedDefinition>]
let kernel (a:int) (adder:int->int) =
let result <- adder a
let transformKernel = <# kernel #> |> Compiler.makeKernel
let add_num b =
fun (a:int) ->
a + b
let run num1 num2 =
let adder = add_num num2
let gpu = Gpu.Default
let num1Gpu = gpu.Allocate(num1)
let adderGpu = gpu.Allocate(adder)
let lp = LaunchParam(1, 1)
gpu.Launch transformKernel lp num1Gpu adderGpu
// return result
let my_result = run 3 7
// my_result should be 10
I found a solution to this in the Alea GPU sample gallery. The simplest example I could see of this is the F# Generic Transform sample. It uses code quotations to compile kernels based on any given function of some specified type (e.g. int -> int -> int)
Related
I have a couple of books that I am going by, but as I am working on my F# problems, I find some difficulties in syntax here. If anyone thinks I should not be asking these questions here and have another book recommendation on a budget, please let me know.
Here is the code that reproduces the problem I am having with my project
[<EntryPoint>]
let main argv =
let mutable x = 0
let somefuncthattakesfunc v = ignore
let c() =
let y = x
ignore
somefuncthattakesfunc (fun () -> (x <- 1))
Console.ReadKey()
0 // return an integer exit code
I am getting the following compile error
The mutable variable 'x' is used in an invalid way. Mutable variables cannot be captured by closures. Consider eliminating this use of mutation or using a heap-allocated mutable reference cell via 'ref' and '!'.
Any clue ?
As the error explains, you can't close over mutable variables, which you are doing in:
let y = x
and
(fun () -> x = 1)
It suggests you use a ref instead if you need mutation:
let x = ref 0
let somefuncthattakesfunc v = ignore
let c() =
let y = !x
ignore
somefuncthattakesfunc (fun () -> x := 1)
As the error message says, mutable variables cannot be captured by closures, use a reference cell instead:
let main argv =
let x = ref 0
let somefuncthattakesfunc v = ignore
let c() =
let y = !x
ignore
somefuncthattakesfunc (fun () -> x := 1)
Console.ReadKey()
0 // return an integer exit code
Also see this answer.
I have googlet a bit, and I haven't found what I was looking for. As expected. My question is, is it possible to define a F# pipeline placeholder? What I want is something like _ in the following:
let func a b c = 2*a + 3*b + c
2 |> func 5 _ 6
Which would evaluate to 22 (2*5 + 3*2 + 6).
For comparison, check out the magrittr R package: https://github.com/smbache/magrittr
This is (unfortunately!) not supported in the F# language - while you can come up with various fancy functions and operators to emulate the behavior, I think it is usually just easier to refactor your code so that the call is outside of the pipeline. Then you can write:
let input = 2
let result = func 5 input 6
The strength of a pipeline is when you have one "main" data structure that is processed through a sequence of steps (like list processed through a sequence of List.xyz functions). In that case, pipeline makes the code nicer and readable.
However, if you have function that takes multiple inputs and no "main" input (last argument that would work with pipelines), then it is actually more readable to use a temporary variable and ordinary function calls.
I don't think that's possible, but you could simply use a lambda expression, like
2 |> (fun b -> func 5 b 6)
Here's a point-free approach:
let func a b c = 2*a + 3*b + c
let func' = func 5 >> (|>) 6
let result = 2 |> func'
// result = 22
I have explained it in details here.
Be aware, however, that someone who would work with your code will not quickly grasp your intent. You may use it for purposes of learning the deeper aspects of the language, but in real-world projects you will probably find a straightforward approach suitable better:
let func' b = func 5 b 6
You could use a new function like that:
let func a b c = 2*a + 3*b + c
let func2 b = func 5 b 6
2 |> func2
#Dominic Kexel's right on the money. If the object isn't really the placement of a placeholder in the chain of arguments, which could have been achieved by a lambda function, but changing their order, then it's more a case of flip than pipe.
From the simple two-argument case
let flip f b a = f a b
// val flip : f:('a -> 'b -> 'c) -> b:'b -> a:'a -> 'c
we need to derive a function
let flip23of3 f a c b = f a b c
// val flip23of3 : f:('a -> 'b -> 'c -> 'd) -> a:'a -> c:'c -> b:'b -> 'd
in order to flip the second and third argument. This could have also been written
let flip23of3' f = f >> flip
let func a b c = 2*a + 3*b + c
2 |> flip23of3 func 5 6
// val it : int = 22
I have given it a try myself. The result is not perfect, but it is as close as I have gotten:
let (|.|) (x: 'a -> 'b -> 'c) (y: 'b) = fun (a: 'a) -> x a y
let func (a:string) b (c:int) = 2.*(float a) + b + 5.*(float c)
let foo = func "4" 9. 5
printfn "First: %f" foo
let bar =
"4"
|> ((func |.| 9.) |.| 5)
printfn "Second: %f" bar
let baz =
9.
|> (func "4" |.| 5)
printfn "Third: %f" baz
The output is, as expected
First: 42.000000
Second: 42.000000
Third: 42.000000
let eval a b =
let r = a + b
printf "calculate.."
r
type Foo() =
member this.Eval = eval 5 10
[<EntryPoint>]
let main argv =
let f = Foo()
let a = f.Eval
let b = f.Eval
0
This calls eval 2 times instead of one time. It seems this.Eval is a function pointer that calls eval every time I call .Eval.
What I really want to have is a variable.
I solved it by doing this...
let eval a b =
let r = a + b
printf "calculate.."
r
type Foo() =
let e = eval 5 10
member this.Eval = e
[<EntryPoint>]
let main argv =
let f = Foo()
let a = f.Eval
let b = f.Eval
0
Is this the correct way of doing this if I just want to have a member variable instead of method?
The behaviour you describe is the way .NET properties always work, whether in C# or F#. The body of the property is evaluated each time the property is read.
In addition to your solution, which is correct, I'd add that it calculates the value when Foo is constructed. You might only want the value to be calculated when you read the property the first time, and if so you can use Lazy to do that:
let eval a b =
let r = a + b
printf "calculate.."
r
type Foo() =
// a lazy computation that will be evaluated the first time .Value is called
let e = lazy eval 5 10
member this.Eval = e.Value
[<EntryPoint>]
let main argv =
let f = Foo()
let a = f.Eval
let b = f.Eval
0
I think that the more idimatic F# style would be:
type Foo() =
let eval a b =
let r = a + b
printf "calculate.."
r
let e = eval 5 10
member this.Eval = e
[<EntryPoint>]
let main argv =
let f = Foo()
let a = f.Eval
let b = f.Eval
0
i.e. you put the eval inside the class with a let binding to hide the implementation
I have these types:
type ShouldRetry = ShouldRetry of (RetryCount * LastException -> bool * RetryDelay)
and RetryCount = int
and LastException = exn
and RetryDelay = TimeSpan
type RetryPolicy = RetryPolicy of ShouldRetry
Now I want composability of the retries; something like this:
let serverOverloaded = [| exnRetry<TimeoutException>;
exnRetry<ServerBusyException> |]
|> Array.map (fun fn -> fn (TimeSpan.FromSeconds(4.0)))
let badNetwork = [||] // etc
let compose p1 p2 =
// http://fssnip.net/7h
RetryPolicy(ShouldRetry( (fun (c,e) ->
let RetryPolicy(ShouldRetry(fn)) = p1
let RetryPolicy(ShouldRetry(fn')) = p2
let (cont, delay) = fn c,e
if cont then cont, delay
else
let (cont', delay') = fn' c,e
cont', delay') ))
let finalPolicy = serverOverloaded |> Array.scan compose (RetryPolicies.NoRetry())
But I'm getting compiler errors on fn, delay and fn', saying "The value or constructor 'fn' is not defined".
I can see two problems in your compose function.
When decomposing p1 and p2, the pattern needs to be wrapped in parentheses (otherwise, the compiler interprets the code as a definition of RetryPolicy function, instead of pattern matching):
let (RetryPolicy(ShouldRetry(fn))) = p1
let (RetryPolicy(ShouldRetry(fn'))) = p2
When calling fn' a bit later, you need to pass it the arguments in a tuple (otherwise, the compiler thinks that you're calling fn' with just a single argument c and then building a tuple):
let (cont', delay') = fn' (c,e)
I didn't check (or tried to run) the whole example, so I don't know if the rest of the code does what you want.
I am trying to fill a list with random numbers and am having diffculty getting the random number part. What I have right now prints out a random number 10 times, what I want is to print out 10 different random numbers
let a = (new System.Random()).Next(1, 1000)
let listOfSquares = [ for i in 1 .. 10->a]
printfn "%A" listOfSquares
any tips or suggestions?
Your code is simply getting one random number and using it ten times.
This extension method might be useful:
type System.Random with
/// Generates an infinite sequence of random numbers within the given range.
member this.GetValues(minValue, maxValue) =
Seq.initInfinite (fun _ -> this.Next(minValue, maxValue))
Then you can use it like this:
let r = System.Random()
let nums = r.GetValues(1, 1000) |> Seq.take 10
let genRandomNumbers count =
let rnd = System.Random()
List.init count (fun _ -> rnd.Next ())
let l = genRandomNumbers 10
printfn "%A" l
When I write a random something dispenser I like to use the same random number generator for each call to the dispenser. You can do that in F# with closures (a combination of Joel's and ildjarn's answer).
Example:
let randomWord =
let R = System.Random()
fun n -> System.String [|for _ in 1..n -> R.Next(26) + 97 |> char|]
In this way, a single instance of Random is 'baked into' the function, reusing it with each call.
There are two problems:
1) In F# functions are supposed to be pure so a function without arguments is considered as final value.
To declare impure function "without arguments", let it take one argument of type unit
let a () = (new System.Random()).Next(1, 1000)
and call it passing unit argument
let list = [ for i in 1 .. 10 -> a () ]
Source
2) New System.Random() instance is created each time when a is called. This results in getting same numbers. To fix this, create the instance only once
let random = new System.Random()
let a () = random.Next(1, 1000)
let list = [ for i in 1 .. 10 -> a ()]
This isn't specific to F#, read explanation for C# for better understanding
You could also avoid declaring an impure function as said by Pavel and just run:
let rnd = Random()
let rndList = [for i in 0..100 do rnd.Next(1000)]
I think one should be careful how to initialize System.Random as it uses the current time as seed. One instance should be enough for the whole app. Injecting random into functions has the advantage that you can use a fixed seed and reproduce with semi randomness, e.g. for testing your logic.
let rnd = System.Random()
let genRandomNumbers random count =
List.init count (fun _ -> random.Next ())
let getRandomNumbersSeeded = getRandomNumbers rnd
let l = getRandomNumbersSeeded 10
printfn "%A" l