【问题标题】:Generic types on function don't correspond properly函数上的泛型类型不正确对应
【发布时间】:2021-10-22 08:31:49
【问题描述】:

我有一般的函数式编程经验,但我是 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# 经验的人有什么建议吗?

【问题讨论】:

  • 我真的不知道你想要达到什么目的。你能发布一些你认为你的函数应该返回的示例值吗?也许您熟悉的其他语言的示例代码可以实现相同的效果?
  • 如果添加行 |> snd |> Seq.ofList 与 Seq.fold 对齐,则可以强制编译,但这没有任何意义。
  • 您的返回类型注释不是您的代码在做什么。您期待一个元组列表,但您正在创建一个 (option, list) 的元组
  • 我应该更清楚一点,该函数应该将每 2 个元素配对成一个元组列表。我想我没有意识到的是它实际上返回了状态,其中包含一个无关的内部值,以及作为两个元素返回的实际列表。
  • 请用您评论中的信息更新问题。

标签: list types functional-programming f#


【解决方案1】:

所以如果你像这样更新你的代码

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. 列表为空,没有对您返回空列表。
  2. 一开始有两个项目,您将它们配对成一个元组并递归处理列表的其余部分
  3. 只剩下一项,我们失败了,因为不可能创建一个没有任何内容的元组*

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

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]) 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-06
    • 2020-10-24
    • 2019-09-29
    • 1970-01-01
    • 1970-01-01
    • 2020-04-14
    • 1970-01-01
    相关资源
    最近更新 更多