F# inherit interface - f#

I have the following class in F# that inherits Microsoft.AspNet.Identity.IIdentityValidator interface:
type MyValidation() =
inherit IIdentityValidator<string> with
member x.ValidateAsync (value:string) : Task<IdentityResult> =
.....
I am getting this error:
This 'inherit' declaration specifies the inherited type but no arguments. Consider supplying arguments, e.g. 'inherit BaseType(args)'.
Why and how do I fix it?

The keyword inherit is just for derived classes. You need to use interface:
type MyValidation() =
interface IIdentityValidator<string> with
member x.ValidateAsync (value:string) : Task<IdentityResult> =
...

Related

How to make an Abstract class that inherits an interface in F#?

I have the following code with an interface and an abstract class.
type INode<'a> =
abstract member Parent:INode<'a>
abstract member Evaluate:unit->'a
abstract member Clone:INode<'a> -> INode<'a>
abstract member SelectRandom:int->INode<'a> option
[<AbstractClass>]
type TerminalNode<'a>() =
interface INode<'a> with
member this.SelectRandom indexOfCurrentNode =
let p = 1.0 / float indexOfCurrentNode
if Random().NextDouble() < p then Some (this:>INode<'a>) else None
I want to implement the hierarchy in this
but the compiler complains that all methods of the interface should be implemented.
What is the correct way to create an Abstract class that implements an interface and implements that interface's one method leaving other methods abstract?
Note: If you cannot see the image, your network is blocking imgur.com.
You can define the abstract members on the type, then provide the implementation which points at those abstract members. For example:
[<AbstractClass>]
type TerminalNode<'a>() as self =
abstract member Parent : INode<'a>
abstract member Evaluate : unit->'a
abstract member Clone:INode<'a> -> INode<'a>
interface INode<'a> with
member this.Parent = self.Parent
member this.Evaluate () = self.Evaluate ()
member this.Clone a = self.Clone a
member this.SelectRandom indexOfCurrentNode =
...
(note the as self in the type line, which lets you refer to the abstract type by the variable name self)

Why can I pass two parameter to Event class

When I look the definition of event class in f#
type Event<'T> =
class
new Event : unit -> Event<'T>
member this.Trigger : 'T -> unit
member this.Publish : IEvent<'T>
end
I can pass only one type on event class like
let nameChanged = new Event<unit>()
But I saw some sample too, that pass two variables like
let propertyChanged = Event<PropertyChangedEventHandler, PropertyChangedEventArgs>()
How could be that be possible?
And when I implement an interface like
module SapHandler
open SAP.Middleware.Connector
type Connector() =
let configurationChanged = Event<RfcDestinationManager.ConfigurationChangeHandler, RfcConfigurationEventArgs>()
interface IDestinationConfiguration with
member self.ChangeEventsSupported() =
false
[<CLIEvent>]
member self.ConfigurationChanged = configurationChanged.Publish
The compiler complain:
The type 'RfcDestinationManager.ConfigurationChangeHandler' has a non-standard delegate type
Why?
The definition of delegate type is:
It's possible because there's another class too:
type Event<'Delegate,'Args (requires delegate)> =
class
new Event : unit -> Event<'Delegate,'Args>
member this.Trigger : obj * 'Args -> unit
member this.Publish : IEvent<'Delegate,'Args>
end
You're getting that error because your delegate for the event is probably missing the first object sender argument which is standard in .net. You can use Control.DelegateEvent<'Delegate> to get around this
let propertyChanged = DelegateEvent<RfcDestinationManager.ConfigurationChangeHandler>()

Implement a C# Interface in F#

I have the following interface in C#
public interface IDog
{
String Bark();
}
I want to create an implementation in F#. I had no problem with this:
type GermanShepherd() =
interface IDog with
member this.Bark() = "Woof"
but when I added a supporting function that is not part of the interface like this:
type GermanShepherd() =
interface IDog with
member this.Bark() = "Woof"
member this.Eat() = "Yummy"
the compiler complained:
Error 1 No abstract or interface member was found that corresponds to this override
Error 2 This value is not a function and cannot be applied*
Is there a way of implementing private/internal functions with a type that implements an interface without those functions being part of the interface? I can't change the interface in my 'real' application b/c there are other projects that implement the interface. None of the examples on MSDN that I found have this particular scenario.
The interface block should only contain functions that are part of the interface, but you can place other functions before the block:
type GermanShepherd() =
member this.Eat() = "Yummy"
interface IDog with
member this.Bark() = "Woof"
If you do not need a public member, then you can go with a private let-bound function:
type GermanShepherd() =
let eat() = "Yummy"
interface IDog with
member this.Bark() = "Woof"
Also note that F# currently only allows explicit interface implementations, which means that you can treat GermanShepherd as IDog, but you won't see IDog members explicitly:
let g = GermanShepherd()
g.Eat() // OK
g.Bark() // Error, interface members are implemented explicitly
let d = g :> IDog // To 'Bark', we need to get 'IDog' first
d.Bark() // OK
One workaround for this is to add the Bark method explicitly as a separate member outside of the interface block. Although there is F# language issue for this too!

Is this an F# bug?

I have an type that is implementing IEnumerable<T> interface, all is ok:
open System
type Bar() =
interface Collections.IEnumerable with
member x.GetEnumerator () = null
interface Collections.Generic.IEnumerable<int> with
member x.GetEnumerator () = null
But things goes wrong if type inherits IEnumerable interface implementation via the base type:
open System
type Foo() =
interface Collections.IEnumerable with
member x.GetEnumerator () = null
type Bar() =
inherit Foo()
interface Collections.Generic.IEnumerable<int> with
member x.GetEnumerator () = null
Code above produces the type inference errors:
The member 'GetEnumerator<'a0 when 'a0 : null> : unit -> 'a0 when 'a0 : null' does not have the correct type to override any given virtual method
The member 'GetEnumerator<'a0 when 'a0 : null> : unit -> 'a0 when 'a0 : null' does not have the correct number of method type parameters. The required signature is 'GetEnumerator : unit -> Collections.Generic.IEnumerator<int>'.
Am I doing something wrong or this is an F# compiler bug?
Microsoft (R) F# 2.0 Interactive build 4.0.30319.1
Update more canonical example:
type IFoo = abstract Bar : obj list
type IFoo<'a> = abstract Bar : 'a list
inherit IFoo
/* ok */
type Foo = interface IFoo with member x.Bar = []
interface IFoo<Foo> with member x.Bar = []
/* fail */
type FooBase = interface IFoo with member x.Bar = []
type FooDerived = interface IFoo<Foo> with member x.Bar = [] // <---
inherit FooBase
/*
error FS0017: The member 'get_Bar : unit -> 'a list' does not
have the correct type to override any given virtual method.
*/
The compiler cannot infer the correct type from your "null"-implementation. Try
open System
type Foo() =
interface Collections.IEnumerable with
member x.GetEnumerator () = null
type Bar() =
inherit Foo()
interface Collections.Generic.IEnumerable<int> with
member x.GetEnumerator () : Collections.Generic.IEnumerator<int> = null
UPDATE:
The reason is, that the type of the GetEnumerator method implemented by the Bar type is ambigous as IEnumerable<'a> implements/inherits the non-generic IEnumerable which also specifies a (non-generic) GetEnumerator method. So, how should the compiler infer, which method exactly you are trying to implement if all he gets is null? Therefore we need a type annotation in this case.
This is not a bug, this is just an type inference fail because of F# may implement inherited interface members in the derived interface implementation declaration:
type IA = abstract A : int
type IB = inherit IA
type IC = inherit IB
type Baz =
interface IC with
member x.A = 1
So in my example I should specify the correct return type explicitly because member x.GetEnumerator() in derived Bar type may match both IEnumerable.GetEnumerator() and IEnumerable<T>.GetEnumerator().

Generics with interfaces in F#

In C# one can state that a generic parameter must implement a certain interface like so:
public class Something<T> where T : IComparable
{
...
}
How does one specify this in F#?
Generic constraints use "when" in F#:
type Foo<'a when 'a :> IComparable> =
member x.Bla = 0

Resources