I am trying to write a riot tag in Fsharp but am unable to do so without changing riot.
In JavaScript I should provide a function like:
function(opts) {
this.on("update",function(opts){
this.opts = opts || this.opts;
});
}
riot will then call this function using Function.prototype.call:
if (impl.fn) { impl.fn.call(this, opts); }
In F# I tried the following:
[<Emit("this")>]
let isThis (x: 'a) : obj = jsNative
let bind fn =
fun o ->
fn (isThis 1) o
[<Emit("$0 === undefined")>]
let isUndefined (x: 'a) : bool = jsNative
bind
(
fun me opts ->
me?on(
"update"
,(
fun opts ->
if not (isUndefined opts) then
me?opts <- opts
()
)
)
)
However; the bind function is transpiled to:
export function bind(fn, o) {
return fn(this)(o);
}
Not currying when I would like it to curry, the output I was looking for is:
export function bind(fn) {
return function(o){
return fn(this)(o);
}
}
The only way I can get this to work is to change riot.js to:
if (impl.fn) { impl.fn(this)(opts); }
And provide my function in F# in the following way:
fun me opts ->
me?on(
"update"
,(
fun opts ->
if not (isUndefined opts) then
me?opts <- opts
()
)
)
Changing 3rd party libraries to satisfy transpiler generated code is not ideal. Is there a way for the transpiler to generate the output I'm looking for?
[update]
A better way to do this that doesn't require changing 3rd party code is to provide the bind function as 3rd party JavaScript:
Then import it and use bind in your template code file:
let JSI =
bind<(obj -> obj -> unit) -> obj>
"../../../js/3rd/JSI.js"
bind
(
fun me opts ->
me?on(
"update"
,(
fun opts ->
if not (isUndefined opts) then
me?opts <- opts
()
)
)
)
You are hitting up against Fable's automatic uncurrying. What you need to do is replace the F# functions with System.Func delegates to prevent Fable from uncurrying.
I was able to get pretty close with this:
[<Emit("this")>]
let jsThis : obj = jsNative
let bind (fn : Func<obj, (obj -> obj)>) =
Func<_, _> (fun o -> fn.Invoke(jsThis) o)
The generated JavaScript:
export function bind(fn) {
return (o) => fn(this)(o);
}
Related
How can I achieve something like this in a clean way?
let's imagine this simple code:
let a () = checkSomeStuff (); None
let b () = do Something (); Some "thing"
let c () = checkSomethingElse (); None
"getOne" {
do! a()
do! b()
do! c()
}
and it would return the first "Some".
I could achieve this exact behavior by using Result where I'd return the value through an Error and continue through with Ok, but that is not readable / nice:
let a () = checkSomeStuff (); Ok ()
let b () = do Something (); Error "thing"
let c () = checkSomethingElse (); Ok ()
result {
do! a()
do! b()
do! c()
}
this would work, but I'm looking to achieve that without mis-using the Result type. Can it be done with the existing expressions?
You don't need a computation expression for this. F# has a built-in function called Seq.tryPick that applies a given function to successive elements of a sequence, returning the first Some result, if any. You can use tryPick to define getOne like this:
let getOne fs =
fs |> Seq.tryPick (fun f -> f ())
Trying it with your example:
let a () = checkSomeStuff ();
let b () = Something ();
let c () = checkSomethingElse ();
let x = getOne [ a; b; c ]
printfn "%A" x // Some "thing"
Some time ago, I wrote a post about imperative computation expression builder that does something along those lines. You can represent computations as option-returning functions:
type Imperative<'T> = unit -> option<'T>
In the computation builder, the main thing is the Combine operation that represents sequencing of operations, but you need a few others to make it work:
type ImperativeBuilder() =
member x.ReturnFrom(v) = v
member x.Return(v) = (fun () -> Some(v))
member x.Zero() = (fun () -> None)
member x.Delay(f:unit -> Imperative<_>) =
(fun () -> f()())
member x.Combine(a, b) = (fun () ->
match a() with
| Some(v) -> Some(v)
| _ -> b() )
let imperative = new ImperativeBuilder()
You can then reimplement your example - to return a value, you just use return, but you need to combine individual operations using return!, because the builder does not support do!:
let a () = imperative { printfn "one" }
let b () : Imperative<string> = imperative { return "result" }
let c () = imperative { printfn "two" }
let f = imperative {
return! a()
return! b()
return! c()
}
f()
You could create a function that does what you want. But you have to think throughout what you want to do.
So, your logic is.
You execute a function that returns an option
Then you check that option. if it is None you execute another function, if it is Some you return the value.
A function like these could look like this:
let getSome f opt =
match opt with
| None -> f ()
| Some x -> Some x
With such a function, you then could write. ***
let x =
checkSomeStuff ()
|> getSome (fun _ -> Something () )
|> getSome checkSomethingElse
But then i think, hmmm.... isn't there a better name for getSome? In some way i want to say:
Execute some code and check if it is Some, or else pick the next thing.
With this in mind, i think. hmm.... isn't there already a Option.orElse? And yes! There is! There is also a Option.orElseWith function, that fits your need even better. So now, you can write.
let y =
checkSomeStuff ()
|> Option.orElseWith (fun _ -> Something () )
|> Option.orElseWith checkSomethingElse
If you have functions with side-effects, then you should use Option.orElseWith, otherwise, you can just sue Option.orElse
***: I assume you have the following function defined
let checkSomeStuff () =
None
let Something () =
Some "thing"
let checkSomethingElse () =
None
I need to compile a quotation into JS string (my main goal is to write MongoDB MapReduce job in F#). I found an example code:
open Microsoft.FSharp.Quotations
open WebSharper
type AR = IntelliFactory.Core.AssemblyResolution.AssemblyResolver
module FE = WebSharper.Compiler.FrontEnd
let compile (expr: Expr) : string option =
let loader = FE.Loader.Create (AR.Create()) (eprintfn "%O")
let options =
{ FE.Options.Default with
References =
List.map loader.LoadFile [
"WebSharper.Main.dll"
"WebSharper.Collections.dll"
"WebSharper.Control.dll"
] }
let compiler = FE.Prepare options (eprintfn "%O")
compiler.Compile expr
|> Option.map (fun e -> e.ReadableJavaScript)
But the compiler output for a simple function, such as
<# fun x -> x + 2 #>
is pretty ugly
(function()
{
var Global=this,Runtime=this.IntelliFactory.Runtime,EntryPoint;
Runtime.Define(Global,{
WebSharper:{
EntryPoint:{
Example:Runtime.Field(function()
{
return function(x)
{
return x+2;
};
})
}
}
});
Runtime.OnInit(function()
{
return EntryPoint=Runtime.Safe(Global.WebSharper.EntryPoint);
});
Runtime.OnLoad(function()
{
EntryPoint.Example();
return;
});
}());
I did not find any option to disable all that WebSharper stuff in the output. Does anyone know a way to do this?
I am looking for a way to define Parameterless lambda expressions in F#, much like the following C# example.
var task = () => {
int x = 3;
DoSomething(x);
}
I tried the following
let task = fun _ ->
let x = 3
doSomething x
It compiles but it gives me task : ('a -> unit) what I am actually looking for is task : (unit -> unit)
The MSDN Documentation does not talk about this. What am I missing here ?
it's just
let task = fun () -> // whatever you need
you example would be:
let task = fun () ->
let x = 3
DoSomething(3)
assuming DoSomething is of type int -> unit - if it returns something else you need
let task = fun () ->
let x = 3
DoSomething(3) |> ignore
to get type unit -> unit
Remark:
Usually you don't write let task = fun () -> ... but just let task() = ...
The thing you missed:
if you write fun _ -> () you are saying you want to take some parameter that you don't mind about - so F# will take the most general (being named 'a here) - this would include unit!
() is the only value of type unit (more or less void from C# ... but a true type in F#)
I want to write a function in F#, that exposes the following type signature to C#:
public static FSharpFunc<FSharpFunc<Unit,Unit>,Unit> foo(Action<Action> f)
In F# I tried writing:
let foo (f : Action<Action>) : ((unit -> unit) -> unit) = ...
But that produces the C# signature:
public static void foo(Action<Action> f, FSharpFunc<Unit,Unit> x)
The F# has treated my code equivalently to:
let foo (f : Action<Action>) (g : unit -> unit) : unit = ...
Of course, these are equivalent to F#, but very different in C#. Is there anything I can do to produce the C# I want? (F# 2.0.0.0)
As a quick hack, I rewrote my F# to:
let foo (f : Action<Action>) ((unit -> unit) -> unit)[] = ...
Then I just use Head in the C#.
If you write let foo x = fun () -> ... then the F# compiler optimizes the code and compiles it as a method that takes two arguments (instead of a method returning function which is what you need). To get a function value as the result, you need to "do something" before returning the function:
// Will be compiled as method taking Action, FastFunc and returning void
let foo1(x : Action<Action>) : (unit -> unit) -> unit =
fun f -> f ()
// Will be compiled as method taking Action and returning FastFunc of FastFunc
let foo2(x : Action<Action>) : ((unit -> unit) -> unit) =
ignore ();
fun f -> f ()
That said, exposing F# function type to C# in any way is a bad pattern and it shouldn't be done. When you have some F# API that is supposed to be used from C#, you should expose functions as delegates, so that C# consumers can use them naturally (without converting Action to F# function explicitly). It is generally easier to write the wrapping on the F# side.
Either:
Add a signature file, with val foo : Action<Action> -> ((unit -> unit) -> unit).
Use a static member of a nominal type, rather than a let-bound value in a module. That is, static member foo (x:Action<Action>) : ((unit -> unit) -> unit) = ...
something like this?
open System
let foo(x : Action<Action>) : (unit -> unit) -> unit = failwith "..."
So I just wanted to ask why this works :
let internal X th =
foo()
th()
bar()
let Start() =
X <| fun () -> ( foo(); bar(); etc... )
And this doesn't work :
let internal XD A =
let X th =
foo()
th()
bar()
(X <| fun () -> A)
let Start() =
XD ( foo(); bar(); etc... )
it's looking like the same for me but first variant works as wrapper and I completely can't understand how second variant works.
I suppose that the confusing thing is that in your second version, the variable A is just a unit. The F# compiler infers this from the fact that you return A from a function that's used as th and the type of th is unit -> unit. This means that foo is called in Start before stepping in XD.
However, it is a bit difficult to tell what results were you expecting. Did you want to pass foo to XD as a function, instead of calling it immediately? If yes, then you'd need:
let internal XD A =
let X th =
foo()
th()
bar()
(X <| fun () -> A()) // Change: Call A with unit argument: 'A ()'
XD foo // Change: Pass a function instead of calling it
The below is the correct code for 2nd version for what you want to achieve (without lambda using lazy values).
let internal XD (A:Lazy<unit>) =
let X th =
foo()
th()
bar()
X <| (fun () -> A.Force())
let Start() =
XD ( lazy(foo(); bar();) )