How to make an Abstract class that inherits an interface in F#? - 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)

Related

How do you declare a type alias in a f# constructor?

type Entity =
abstract member newEntity: Entity
abstract member clearEntity : Entity
abstract member lastEntity : Entity
abstract member loadData: Entity
abstract member saveData: Entity -> unit
abstract member deleteData: Entity -> unit
Is there any way to avoid repeated writes Entity word?
type Entity =
type T = Entity
abstract member newEntity: T
abstract member clearEntity : T
abstract member lastEntity : T
abstract member loadData: T
abstract member saveData: T -> unit
abstract member deleteData: T -> unit
I want an implementation like this, Scala should be able to do it
You can't put a type declaration inside another. What you can do is make mutually recursive type declarations:
type Entity =
abstract member newEntity: T
abstract member clearEntity : T
abstract member lastEntity : T
abstract member loadData: T
abstract member saveData: T -> unit
abstract member deleteData: T -> unit
and T = Entity

F# inherit interface

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> =
...

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!

Inherit from Seq

I want to create my own custom collection type.
I define my collection as:
type A(collection : seq<string>) =
member this.Collection with get() = collection
interface seq<string> with
member this.GetEnumerator() = this.Collection.GetEnumerator()
But this doesn't compile No implementation was given for 'Collections.IEnumerable.GetEnumerator()
How do i do this?
In F# seq is really just an alias for System.Collections.Generic.IEnumerable<T>. The generic IEnumerable<T> also implements the non-generic IEnumerable and hence your F# type must do so as well.
The easiest way is to just have the non-generic one call into the generic one
type A(collection : seq<string>) =
member this.Collection with get() = collection
interface System.Collections.Generic.IEnumerable<string> with
member this.GetEnumerator() =
this.Collection.GetEnumerator()
interface System.Collections.IEnumerable with
member this.GetEnumerator() =
upcast this.Collection.GetEnumerator()

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().

Resources