首页 > 解决方案 > 为什么 F# 不喜欢将类型('a list list)作为输入?

问题描述

*我编辑了我的原始帖子以包含更多信息。

我正在处理一个 F# 分配,我应该在其中创建一个函数,该函数将“任何列表列表”作为输入并输出“任何列表”。它应该能够将列表列表连接成一个列表。

这是我的函数的样子:

let llst = [ [1] ; [2;3] ; ['d';'e';'f'] ]
let concat (llst:'a list list) : 'a list = 
    List.concat llst

List.iter (fun elem -> printf "%d " elem) concat

该解决方案或多或少直接从微软使用 List.concat 函数的示例复制而来,唯一的例外是输入/输出类型的规范。

当我运行代码时,我收到此错误:

concat.fsx(7,43): error FS0001: This expression was expected to have type
    ''a list'
but here has type
    ''b list list -> 'b list'

所以看来 concat 正在把我的 llst 变成一个字符列表,我不明白。

谁能帮我理解为什么会出现这种类型错误以及如何编写一个采用我需要的类型的函数?

标签: f#

解决方案


问题出在您执行该concat功能的某个地方。如果没有看到您的代码,很难说出确切的位置,但由于这是一项任务,实际上最好解释错误消息告诉您的内容,以便您自己找到问题。

错误消息告诉您,F# 类型推断算法在您的代码中找到了一个位置,您编写的内容的实际类型与该位置的预期类型不匹配。它还告诉您两种不匹配的类型是什么。例如,假设你写了这样的东西:

let concat (llst:'a list list) : 'a list = 
  llst

您将在第二行得到错误,因为llstis的类型'a list list(编译器从您在第 1 行给出的类型注释中知道这一点),但预期的类型与函数的结果类型相同,即'a list- 也由您的类型注释指定。

因此,为了帮助您找到问题 - 查看您遇到错误的确切位置,并尝试推断编译器为什么认为实际类型是'a list list,并尝试理解为什么它期望'a list的类型应该在这个地方。


推荐阅读