How do I write a delegate with params in F#? - f#

I have a C# delegate that I need to replicate in F#:
public delegate object InvokeDelegate(string method, params object[] parameters)
How do I replicate this in F#?
I tried:
type InvokeDelegate = delegate of (string * (obj [])) -> obj
I'm not sure what's special about this, just that calling the delegate on some library functions doesn't work if I use the F# delegates that I've tried.
I thought it might be the params keyword, but I don't know how to do that in F#.

It's a little messy since F# doesn't have params syntax sugar, but here's how you can do it:
open System
type InvokeDelegate = delegate of method: string * [<ParamArray>] parameters: obj [] -> obj
This will compile down into the following C# equivalent delegate:
[Serializable]
[CompilationMapping(SourceConstructFlags.ObjectType)]
public delegate object InvokeDelegate(string method, params object[] parameters);
See here for param arrays: https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/parameters-and-arguments#parameter-arrays
And here for delegates: https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/delegates
Note that your definition was also a tupled definition (the parentheses did that), compiling down into a delegate with a simple tuple as a parameter. This is probably one of the quirkier areas of F#.

Related

NSubstitute and FSharp - Mocking an FSharp Function

Given an interface that has a FSharp style function.
type IUseless =
abstract member Listify: string -> int -> string list
How would you mock the function?
let substitute = NSubstitute.Substitute.For<IUseless>()
substitute.Listify.Returns(??? what would even go here ???)
I wouldn't expect to be able to mock it like a normal method, or a value that contains a function (although that's sort of what it represents).
So I'm curious if anyone has successfully mocked an FSharp function with a typical .NET mocking library.
First: yes, you can totally mock this like a normal method:
let substitute = NSubstitute.Substitute.For<IUseless>()
(substitute.Listify "abc" 5).Returns ["whatevs"]
This works, because F# compiles this definition like a normal .NET method, despite the curried syntax. This is done partly for interop and partly for performance.
But second: if I were you, I would rather skip the whole NSubstitute business altogether and use inline interface implementation instead:
let substitute = { new IUseless with member x.Listify a b = ["whatevs"] }
This is cleaner, better typechecked, and a lot faster at runtime.

What does a colon after a tuple but before another type mean within a method signature?

What does a colon that's positioned after a tuple but before another type mean within a method signature?
Here's the syntax:
member this.Post (portalId : string, req : PushRequestDtr) : IHttpActionResult =
Here's the context:
type PushController (imp) =
    inherit ApiController ()
    member this.Post (portalId : string, req : PushRequestDtr) : IHttpActionResult =
        match imp req with
        | Success () -> this.Ok () :> _
        | Failure (ValidationFailure msg) -> this.BadRequest msg :> _
        | Failure (IntegrationFailure msg) ->
            this.InternalServerError (InvalidOperationException msg) :> _
Specifically, what does this method signature mean?
Does this method take two parameters or one parameter?
I understand this:
(portalId : string, req : PushRequestDtr)
But I'm confused about this syntax that's appended to the end of it:
: IHttpActionResult
That would be the return type, i.e. the type of the value returned by the method.
From the F# online docummentation:
https://learn.microsoft.com/en-us/dotnet/articles/fsharp/language-reference/members/methods
// Instance method definition.
[ attributes ]
member [inline] self-identifier.method-nameparameter-list [ : return-type ]=
method-body
In this case return_type is IHttpActionResult, which means this method will return an object that implements the IHttpActionResult interface.
Also, although (portalId : string, req : PushRequestDtr) looks like a tuple (and in a certain way it is syntax-wise) it is not, in fact, treated as a tuple. In this case, this is a specific F# syntax for declaring method arguments while defining a method of a F# object. This is the part represented by method-nameparameter-list in the F# method template declaration. This means that the Post method receives two arguments: portalId and req, not a single argument as a tuple.
Specifically, this syntax of a list of arguments that looks like a tuple but that they are not a tuple has to be used when declaring method arguments instead of function arguments. The member keyword is the one that makes this line a method declaration instead of a function declaration.
--
Regarding the :> operator: This is a cast operator. More specifically a upcasting operator (which changes the type of a more derived type to the type of some higher type in the type hierarchy).
In this case, it is being used to explicitly tell the compiler that each branch in the match expression will return some type that is derived (or that implements) IHttpActionResult. I am not quite sure why this cast is needed (something to do with F# not being able to infer the correct type in this context, see this other question: Type mismatch error. F# type inference fail?) but in fact, it is casting every possible return value to IHttpActionResult which is the method's return type.
https://learn.microsoft.com/en-us/dotnet/articles/fsharp/language-reference/casting-and-conversions

How do you write a generic F# delegate declaration?

So, how do you write a generic delegate declaration in f#?
I want to get the equivalent of this c# declaration:
public delegate Result<TOutput> Parser<TInput, TValue>(TInput input);
I haven't been able to find documentation on how this might be achieved, even though it's a quite common to have to write generic delegates.
Any ideas or pointers?
You can define a generic delegate as follows:
type Parser<'TInput, 'TOutput> = delegate of 'TInput -> Result<'TOutput>
In F#, the generic parameters are written with a single quote at the beginning (to distinguish them from normal types), so that's why you need'TInput.
Just for the record, I don't think I ever needed to define a delegate in F#. I guess they are still useful for C# interop, but even then, I would probably just define a type alias for a Func delegate, or (when you are not going to be calling this from C#, just an ordinary F# function):
// Alias for a standard .NET delegate
type Parser<'TInput, 'TOutput> = System.Func<'TInput, Result<'TOutput>>
// Alias for a normal F# function
type Parser<'TInput, 'TOutput> = 'TInput -> Result<'TOutput>

F#: Implement an inline method (On Inteface) to avoid using a real type

I'm trying to see if inline can be applied to an implemented method so that the specific type coming in doesn't have to be spelled out. I've done this with one off (Not inherited/implemented) methods, but trying to also do using an interface.
type public IBookInteraction =
abstract inline CreateBook : 'a -> MethodResult<BasicBookModel>
type public BookInteraction(?userInteraction) =
interface IBookInteraction with
member inline x.CreateBook(bookModel) =
let userId = (^a : (member UserId : Int32 with get) (bookModel))
MethodResult<BasicBookModel>()
I'm guessing there's a way to do this, but it doesn't work with a generic operator(?) in the interface method signature.
I don't believe it's possible to have abstract inline methods. Even if you could, your code wouldn't work, because your interface definition promises that users can call it with any 'a, but your implementation places a static member constraint on 'a - in a hypothetical world where F# supported abstract inline methods, the declaration of the method on the interface would also need to include the constraint.
In any case, to see why it's not possible for F# to support abstract inline methods, consider what inline means: the code that you write to implement the method will be essentially copied and pasted into the call site. However, with an abstract method, you don't know the concrete type that is defining the implementation of the method, so there's no way to figure out at compile time what code you're supposed to be inlining!
I think the correct answer is interface implementations may not be inlined. I'm not sure why it's allowed in the interface definition.

F# all permutations of C# class

I have a C# class MyClass.
And I would need to implement f# method returning all
possible permutations of items in a IList
Problem is that MyClass contains a method
bool CheckOrder(IList predecessors) returning true if the
instance of MyClass can be placed in the permutation after instances
of MyClass in the parameter. Otherwisem this method returns false.
Please, could anyone advise me how to implement a proper F# function.
Update:
Please, could you outline F# code of the method test considering my C# class having method: bool CheckOrder(IList predecessors)
Your CheckOrder method expects an IList<MyClass>, so we should maybe work with arrays in F#, since arrays implement the IList interface.
For every element in a permutation candidate, we need to check whether all its predecessors in the array are legal. To me, that looks like a job for a fold operation where the fold's state parameter is a tuple of the "array so far" and a boolean success flag.
let checkPermutation (permutation:MyClass[]) =
let prefix, success =
permutation
|> Array.fold (fun (prefix:MyClass[], success) element ->
if not success then
(Array.empty, false) // once failed, the result is false
else
(Array.append [|element|] prefix, element.CheckOrder prefix)
)
(Array.empty, true)
success
Array.append is probably quite inefficient. If this is too slow, you should consider using a ResizeArray (which is the same as a C# List) instead.

Resources