函数的泛型类型不正确对应

Generic types on function don't correspond properly

我有一般的函数式编程经验,但我是 F# 的新手,无论我尝试什么我都无法编译此代码:

let group2<'T> (sq: seq<'T>) : seq<'T * 'T> = 
    Seq.fold (fun (p, l) b -> match p with
                              | None   -> (Some b, l)
                              | Some v -> (None, (v, b) :: l)) (None, []) sq

我不明白这条错误消息想告诉我什么,我也想不通为什么它不能按原样编译;

main.fs(2,19): error FS0001: This expression was expected to have type
    'seq<'T * 'T>'    
but here has type
    ''a * 'b'    

main.fs(4,65): error FS0001: This expression was expected to have type
    'seq<'T * 'T>'    
but here has type
    ''a * 'b'  

有更多 F# 经验的人有一些建议吗?

因此,如果您像这样更新代码

let group2<'T> (sq: seq<'T>) : seq<'T * 'T>  = 
    Seq.fold (fun (p ,l) b -> match p with
                              | None   -> (Some b, l)
                              | Some v -> (None, (v, b) :: l)) (None, []) sq
    |> snd
    |> List.rev
    |> Seq.ofList

它可以工作(通过删除状态,然后从列表转换回序列)。例如

group2 [1;2;3;4]

产量

[(1, 2); (3, 4)]

它不是很地道,因为它混合了序列和列表。

仅用于(偶数)列表的更惯用的代码:

let rec group2 (xs:'T list) =
    match xs with
    | [] -> []
    | x::y::xs -> ( x, y)::group2 xs
    | _ -> failwith "not even"

基本上你处理3个选择,

  1. 列表为空,没有对你return一个空列表。
  2. 开头有两个项目,您将它们配对成一个元组并递归处理列表的其余部分
  3. 只剩下一项,我们失败了,因为创建一个什么都没有的元组是不可能的*

如果你想考虑奇数列表,你可以使用选项类型:例如None/Some

let rec group2 (xs:'T list) =
    match xs with
    | [] -> []
    | [x] -> [Some x, None]
    | x::y::xs -> (Some x,Some y)::group2 xs

最后,您可以将 chunkBySize 库函数用于(偶数)列表或序列:

[1;2;3;4]
|> Seq.chunkBySize 2
|> Seq.map (fun a -> a.[0], a.[1]) 

[1;2;3;4]
|> List.chunkBySize 2
|> List.map (fun a -> a.[0], a.[1])