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

fai*_*rjm 1 f#

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

我无法声明变量使用 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 = []  
Run Code Online (Sandbox Code Playgroud)

它工作,但不能添加元素.result <- new NumToken(lineNum, value) :: result只是说它需要'a但是在这里NumToken

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

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

谢谢你的帮助.

Tom*_*cek 7

使用类层次结构建模令牌并创建令牌列表时,列表的类型需要是特定的.你可以退货list<Token>list<NumToken>.

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

result <- (NumToken(lineNum, value) :> Token) :: result 
Run Code Online (Sandbox Code Playgroud)

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

type Token = 
  | NumToken of int
  | StrToken of string
Run Code Online (Sandbox Code Playgroud)

然后你可以编写一个list<Token>只通过写入返回的函数

result <- (NumToken 42) :: result
Run Code Online (Sandbox Code Playgroud)

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