Formatting fluent/method chaining code from C# in F# - f#

Some apis like Ninject use fluent style apis, example:
Bind<ISomething>()
.To<Something>()
.WithConstructorArgument("arg1", "somevalue")
.OnActivation(x => x.DoSomething())
When I try format the code like this in F# the compiler complains at the whitespace between method calls.
Is it possible to put the method calls on seperate lines? I was thinking something like the pipelining operator |> but not exactly sure how in this case.
How should this be formatted in F#?

Are you sure this doesn't work?
Bind<ISomething>()
.To<Something>()
.WithConstructorArgument("arg1", "somevalue")
.OnActivation(fun x -> x.DoSomething())
(note one space before the .s)
Yeah, it's fine:
type ISomething = interface end
type Something = class end
type Foo() =
member this.To<'a>() = this //'
member this.WithConstructorArgument(s1,s2) = this
member this.OnActivation(x:Foo->unit) = this
member this.DoSomething() = ()
let Bind<'a>() = new Foo() //'
let r =
Bind<ISomething>()
.To<Something>()
.WithConstructorArgument("arg1", "somevalue")
.OnActivation(fun x -> x.DoSomething())
So long as you have some leading whitespace when you try to continue a single expression onto multiple lines, you're ok.
(Note that pipelining in general won't work unless you have APIs designed for it with curried method parameters.)

Related

Is there a way to use let statements in classes with inline methods?

A simplified example that gives an error because let str is private:
let launch = printfn "%s"
type Test() =
let str = "Hello"
member inline t.A() =
launch str
I've discovered statically resolved type parameters in F# and after a rewrite have a neural net library where 95% of the functions are inlined as a result, including class methods. I wrote it as a F# script at first, forgetting that there is a difference between script mode and compiled mode in their treatment of inlined methods.
let test = // Is this the only choice?
let str = "Hello"
fun () ->
launch str
Is there any way to use body initializers in F# classes or should I rewrite the classes to be higher order functions like the above? Thankfully, that would not be a problem here.
This question is related to this one, but I thought I'd ask again since it has been 5 years.
Actually I was wrong. It is true that the higher order function example does work in the simplified case above, but I've realized that lambda arguments cannot be statically resolved. I thought of using records for a bit and then tried this:
type Test() =
let str = "Hello"
member t.Str = str
member inline t.A() =
launch t.Str
Private member can be exposed and this will compile. Doing it like the above would be satisfactory.

Building Code Expressions "Manually"

I want to construct a F# code expression. However I dont want to do that via code quotations but construct it via objects.
However the documentation on how to do that is pretty scarce.
Given the following snippet
type Foo = { foo = string}
let bar = {foo = "foo"}
let ex = <# bar.foo #>
this yields for ex.
PropertyGet (Some (ValueWithName ({foo = "foo";}, bar)), foo, [])
But I simply cant replicate that exact term above. For example I dont find anything on the constructor ValueWithName.
So how can I
<# bar.foo #> = PropertyGet (Some (ValueWithName ({foo = "foo";}, bar)), foo, [])
Using the library to construct quotations manually is quite difficult to do correctly, so I'd highly recommend using quotation literals wherever you can. However, here's how to achieve your example if you want to:
open Microsoft.FSharp.Quotations
Expr.PropertyGet(
Expr.ValueWithName({ foo = "foo" }, "bar"),
typeof<Foo>.GetProperty("foo"))

How to expose the type as friendly as possible to both C# and F#?

For example, if I have written a module in F#
module Lib
type A =
member this.x1 x = ...
let helpa x = ...
let helpb x = ...
type B =
member this.y1 x = ...
let helpc x = ...
typeA with
member this.x2 x = ...
typeB with
member this.y2 x = ...
It works well in F# by open Lib, However, if I want to consume it in C# (where I am only interested in types and member functions in Lib), each time I create a type I have to new Lib.A(...). It becomes rather annoying there is no way to omit the module names. Calling a static method like Lib.A.C() is even more of a hassle.
Then I try to replace module with namespace, each time I introduce some helper functions I have to create a new module with a new name. Occasionally I can manage to rearrange all helper functions into 1 module, but that would result in less readable code somehow.
What would be a better structure for this?
Wish I had: Using * = Lib.* for C#.
F# offers more flexibility than C# here, so I would expose it to C# in the standard way, i.e., enclose types in a namespace. Something like this, I think, offers the best of both worlds:
namespace Lib
type A =
member this.x1 x = ()
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module A =
let helpa x = ()
let helpb x = ()
type B =
member this.y1 x = ()
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module B =
let helpb x = ()
type A with
member this.x2 x = ()
type B with
member this.y2 x = ()
The F# collections follow a similar design. You can use the [<AutoOpen>] and [<RequireQualifiedAccess>] attributes to further control how the modules are used from F#.
I think you already mentioned the best option in your answer - define the file with namespace declaration at the top (this way, you can write just using Lib in C#) and then place all helper functions in modules.
Helper functions that are clearly associated with some type (e.g. with A) could be placed into a module named A (similarly to F# functions in the List module that are associated with the List<'T> type).
This is a bit more work, because you need to mark the module with a special attribute (to avoid name clash), but it will be easy to use from both F# and C# (and I think having nice use is more important than saving a few keystrokes when building the library):
namespace Lib
// Declaration of the 'A' type and helper functions in 'A' module
type A() =
member this.x1 x = 10
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module A =
let helpa (x:A) = x.x1
let helpb (x:A) = x.x1
// Declaration of the 'B' type and helper functions in 'B' module
type B() =
member this.y1 x = 10
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module B =
let helpc (x:B) = x.y1
// Member augmentations for easy use from C#
type A with
member this.x2 x = A.helpa this
type B with
member this.y2 x = B.helpc this

How to get a reference to a function that doesn't take parameters in F#?

I sometimes have the need to get the function itself, not the value, of a zero-parameter function in F#, for instance for memoization. I.e., I have this:
let memoize (f: 'a -> 'b) =
let dict = new Dictionary<'a, 'b>()
let memoizedFunc (input: 'a) =
match dict.TryGetValue(input) with
| true, x -> x
| false, _ ->
let answer = f input
dict.Add(input, answer)
answer
memoizedFunc
and this works perfectly, but now I have the following function:
let private getDataSlowOperation =
// implementation
and when I try to memoize that, it gives a type mismatch (essentially the mismatch between the return type of getDataSlowOperation and the 'a type). I can solve this by changing the function as follows:
let private getDataSlowOperation bogus =
// implementation
Now this works, but it seems odd to have to change the function signature to get memoization to work:
let memoGetDataSlowOperation = memoize getDataSlowOperation
I've experimented with inline fun declarations, but this creates, of course, a new anonymous function and the memoization doesn't work with that. Any ideas how to resolve this? Any keyword / operator I've forgotten about?
What you defined is not a function, it's just a value.
In order to define it as a function you can write this:
let private getDataSlowOperation() =
// implementation
UPDATE
To summarize the discussion:
This is the right way to write it as a function, however the code would still not work but that's a different problem.
The code would fail at runtime because () is compiled to null and by using a Dictionary you can't use null for the Key. You can use a Map instead.
John pointed out that memoization for functions without parameters makes no sense, I agree.
Still, if you use a Dictionary for functions with parameters you will run into the same problem with values that are compiled to null, ie: None

Alternatives to functors in F#

I would like to write the following:
module A =
type Token
let foo Token =
module B =
type Token
let foo Token =
let run (m : module) =
m.B
|> m.foo
basically a function that's generic in the module. Is there a way to do this in F#?
As kvb pointed out in a comment, it is hard to give an answer without a realistic example, because the best approach will depend on what you're actually trying to do.
In this trivial example, I would probably use F# interface to represent Token and add Foo as a member. Assuming that Foo returns an int, you can write the definition like this:
type Token =
abstract Foo : unit -> int
Then you can implement different tokens either using classes (which is quite heavyweight) or using object expressions. For example:
let tok = { new Token with
member x.Foo () = 42 }
The code that corresponds to your run function is just a call of the Foo member: tok.Foo()

Resources