如何将具有公共基类的子类型的实例添加到FSharp中的同一列表?

时间:2016-02-12 11:37:59

标签: f#

我有一个名为Token的基本抽象类和一些子类型,如NumTokenStrToken
我想把他们的实例放在同一个列表中。

我无法声明变量使用let l = list<'a when 'a :> Token>

然后,我写了

    let extractToken<'a when 'a :> Token>(lineNum:int, line:string) : 'a list option =
        let mutable result : 'a list = []  

虽然有效但无法添加元素。result <- new NumToken(lineNum, value) :: result只是说它需要'a,但这里是NumToken

现在我可以使用new NumToken(lineNum, value) :> Token并声明Token list 它虽然看起来很丑陋(但我知道fsharp不会自动投射......)。

list<_ :> Token>也不起作用,它只接受一个子类型。

寻求帮助。

1 个答案:

答案 0 :(得分:7)

使用类层次结构建模令牌并创建令牌列表时,列表的类型需要是特定的。您可以返回files: [ 'base/base.js', 'base/base-base.js', 'src/*.js' 'test/spec/*.js', ] list<Token>

具有list<NumToken>约束的灵活类型很少有用 - 通常,当你有一个函数需要一些其他函数并返回其他函数产生的任何函数时,所以我认为你不需要它们。您可以使用when并写:

list<Token>

也就是说,使用类层次结构在F#中建模令牌并不是一个好主意。 F#支持有区别的联合,它们更适合这类问题:

result <- (NumToken(lineNum, value) :> Token) :: result 

然后你可以编写一个只通过编写

返回type Token = | NumToken of int | StrToken of string 的函数
list<Token>

虽然取决于你在做什么,但避免突变可能也是一个好主意。