列表<t>与F#中的T列表给出了类型错误</t>

时间:2014-03-21 22:01:01

标签: f# pattern-matching

我想要一个收到seq<DateTime*int>并返回DateTime*seq<DateTime*int>的函数。元组的第一部分是传入参数的第一个元素的DateTime,列表是其余元素。

我试图以这种方式在F#中编写代码,但它会产生编译错误:

static member TheFunc(lst: seq<DateTime*int>)=
    match lst with
    | (h_d, h_i)::tail -> (h_d,tail)
    | [] -> raise (new ArgumentException("lst"))

(h_d, h_i)中突出显示的错误是:

The expression was expected to have type
    seq<DateTime*int>
but here has type
    'a list

如果我在签名中使用列表而不是序列:

static member TheFunc(lst: List<DateTime*int>)=
    match lst with
    | (h_d, h_i)::tail -> (h_d,tail)
    | [] -> raise (new ArgumentException("lst"))

使用:

The expression was expected to have type
    List<DateTime*int>
but here has type
    'a list

知道为什么这不起作用以及如何使其发挥作用?

2 个答案:

答案 0 :(得分:2)

使用(DateTime * int) list代替List<DateTime * int>

如果您打开List<T>,则T listSystem.Collections.Generic类型会有所不同。值得注意的是,如果你没有,他们就不会!

如果你这样做,那么List<int>是C#中通常使用的可变列表的一个实例:

> open System.Collections.Generic   
> let t0 = typeof<List<int>>
val t0 : Type = System.Collections.Generic.List`1[System.Int32]

int list是F#中通常使用的不可变列表的实例:

> let t1 = typeof<int list>
val t1 : Type = Microsoft.FSharp.Collections.FSharpList`1[System.Int32]

令人困惑的是,如果您 open System.Collections.Generic,它们是相同的:

(* New session *)
> let t0 = typeof<List<int>>
val t0 : Type = Microsoft.FSharp.Collections.FSharpList`1[System.Int32]
> let t1 = typeof<int list>
val t1 : Type = Microsoft.FSharp.Collections.FSharpList`1[System.Int32]    

答案 1 :(得分:0)

问题是您要尝试将seqlist匹配(如错误所示)。你想用

static member TheFunc(lst: seq<DateTime*int>)=
    match lst |> List.ofSeq with
    | (h_d, h_i)::tail -> (h_d,tail)
    | [] -> raise (new ArgumentException("lst"))

(将列表转换为seq,然后将模式匹配)。

或者,使用

static member TheFunc(lst: list<DateTime*int>)=

l中的小写list是因为您可能打开了System.Collections.Generic,而List与F#list <不同/ p>