Interface 具有抽象类的通配符类型推断

Interface 具有抽象类的通配符类型推断,interface,f#,abstract-class,type-inference,Interface,F#,Abstract Class,Type Inference,在改进我的F#的过程中,我一直在尝试类型推断和 当(a)类型签名乱七八糟,以及(b)我不知道类型签名会是什么样子(我通常从抽象类开始,然后派生)时,我经常对为中的抽象方法准备类型签名所需的工作感到困惑 这是一个(b)场景的玩具示例,我不知道派生类是否需要额外的参数来完成它们的任务。我只知道我想让这个类呈现一个事件(feedAvailable),并有两个操作(Activate和Deactivate)返回单元 [<AbstractClass>] type DataSource () =

在改进我的F#的过程中,我一直在尝试类型推断和

当(a)类型签名乱七八糟,以及(b)我不知道类型签名会是什么样子(我通常从抽象类开始,然后派生)时,我经常对为中的抽象方法准备类型签名所需的工作感到困惑

这是一个(b)场景的玩具示例,我不知道派生类是否需要额外的参数来完成它们的任务。我只知道我想让这个类呈现一个事件(
feedAvailable
),并有两个操作(
Activate
Deactivate
)返回单元

[<AbstractClass>]
type DataSource () = 
    let mutable isActive = false
    let feedAvailable = new Event<_> ()
    abstract member Activate: _ -> unit
    abstract member Deactivate: _ -> unit

type NotAbstract () =
    inherit DataSource ()
    override this.Activate (a: int) = 
        printfn "active: a = %i" a
    override this.Deactivate (a: float) = 
        printfn "Stopped: a = %i" a

type NotAbstractTextual () =
    inherit DataSource ()
    override this.Activate (a: string, b: int) = 
        printfn "active: a = %i" a
    override this.Deactivate (a: string, b: string) = 
        printfn "Stopped: a = %i" a

我很确定你想做的是不可能的

您正在尝试将数据源上的两个成员函数设置为泛型,但将子类型设置为特定的。当泛型参数不是实际类型的一部分时,不能这样做。这不是F#的问题,你也不能在C#中完成,请参见下面的C#中的操作

对不起,我不能给你更深入的解释

public abstract class Foo
{
    public abstract string Activate<T>(T t);
    public abstract string Deactivate<T>(T t);
}

public class Bar : Foo
{
    public override string Activate<T>(T t)
    {
        throw new NotImplementedException();
    }

    public override string Deactivate<T>(T t)
    {
        throw new NotImplementedException();
    }
}
公共抽象类Foo
{
公共抽象字符串激活(T);
公共抽象字符串停用(T);
}
公共类酒吧:富
{
公共覆盖字符串激活(T)
{
抛出新的NotImplementedException();
}
公共覆盖字符串停用(T)
{
抛出新的NotImplementedException();
}
}

据我所知,没有理由让
classusingthedasource
的构造函数参数与
的ds
类型完全相同;只要是抽象类型的数据源就足够了。所以你可以这样写:

type ClassUsingTheDataSource<'a, 'b> (dataSource: DataSource<'a, 'b>) = // ...
使用数据源(数据源:数据源)=/。。。
如果您担心的是,您仍然可以在没有显式强制转换的情况下调用此构造函数:

let f() =
    ClassUsingTheDataSource(NotAbstract())

// val f : unit -> ClassUsingTheDataSource<'a, 'b>
let f()=
使用DataSource(NotAbstract()进行分类
//val f:单位->使用数据源分类

我认为,再仔细想想,我最初的定义
类型ClassUsingTheDataSource DataSource>(DataSource:'ds)=..
可以使用
#DataSource
进行压缩(如果我没有弄错的话),它并不等同于
类型ClassUsingTheDataSource(DataSource:DataSource)=/..
。请参见示例:。我说得对吗?这确实不完全相同。我的意思是,您确定需要
'ds:>数据源吗?在大多数情况下,将
数据源
作为参数就足够了(而且更简单)。
type ClassUsingTheDataSource<'a, 'b> (dataSource: DataSource<'a, 'b>) = // ...
let f() =
    ClassUsingTheDataSource(NotAbstract())

// val f : unit -> ClassUsingTheDataSource<'a, 'b>