不确定在 OCaml 中创建函数时如何解决类型错误
Unsure how to address type error when creating a function in OCaml
下面的例子解释了代码应该做什么,我在下面提供了错误消息。这是针对 class 的 pset,因此我非常感谢任何代码解决方案附带的解释!对我来说最重要的是我理解它,因为我们下周有期中考试,从长远来看,仅仅把我的一部分 pset 正确并不能帮助我 运行。
(* the student's name and year *)
type name = string
type year = int
type student = name * year
(* filter_by_year : returns the names of the students in a given year
* Example : let students = [("Joe",2010);("Bob",2010);("Tom",2013)];;
* filter_by_year students 2010 => ["Joe";"Bob"] *)
let filter_by_year (slist:student list) (yr:year) : name list =
let newlist = List.filter ~f:(fun x -> match x with
| (a,b) -> b = yr) slist in
List.fold_right ~init:[] ~f:(fun x r-> match x with
| (a,_) -> r :: a)
;;
错误:此表达式的类型为“列表”
但表达式应为 'a 类型
类型变量 'a 出现在 'a 列表中
首先让我们尝试以更具可读性的方式重写您的代码
let filter_by_year (slist:student list) (yr:year) : name list =
let newlist = List.filter slist ~f:(fun (a,b) -> b = yr) in
List.fold_right newlist ~init:[] ~f:(fun (a,_) r -> r :: a)
可以直接在形参中进行模式匹配,所以不用写
fun x -> match x with
| (a,_) -> a = d
你可以写:
fun (a,_) -> a = d
当代码干净时,可以更容易地找到错误。当您向右折叠时(这是 CS51,对吗?),您使用的是 cons 运算符 ::
,它需要左侧的列表元素和右侧的列表。看来你选错了方向。
您的错误来自错误使用 cons 运算符 ::
。另外,你本可以做得更好!
请注意,您的 List.fold_right
的行为与 List.map
完全相同。所以你可以使用它并且更简洁:
let filter_by_year (slist:student list) (yr:year) : name list =
let newlist = List.filter slist ~f:(fun (a,b) -> b = yr) in
List.map newlist ~f:fst
我们还可以注意到,当您只能遍历一次时,您却对列表进行了两次遍历(这次使用 fold_right
):
let filter_by_year slist yr =
List.fold_right slist ~init:[]
~f:(fun (a,b) result -> if b = yr then a::result else result )
请注意,如果你想做一个真正的应用程序,你应该使用一些其他的数据结构来避免遍历整个 "database"。
下面的例子解释了代码应该做什么,我在下面提供了错误消息。这是针对 class 的 pset,因此我非常感谢任何代码解决方案附带的解释!对我来说最重要的是我理解它,因为我们下周有期中考试,从长远来看,仅仅把我的一部分 pset 正确并不能帮助我 运行。
(* the student's name and year *)
type name = string
type year = int
type student = name * year
(* filter_by_year : returns the names of the students in a given year
* Example : let students = [("Joe",2010);("Bob",2010);("Tom",2013)];;
* filter_by_year students 2010 => ["Joe";"Bob"] *)
let filter_by_year (slist:student list) (yr:year) : name list =
let newlist = List.filter ~f:(fun x -> match x with
| (a,b) -> b = yr) slist in
List.fold_right ~init:[] ~f:(fun x r-> match x with
| (a,_) -> r :: a)
;;
错误:此表达式的类型为“列表” 但表达式应为 'a 类型 类型变量 'a 出现在 'a 列表中
首先让我们尝试以更具可读性的方式重写您的代码
let filter_by_year (slist:student list) (yr:year) : name list =
let newlist = List.filter slist ~f:(fun (a,b) -> b = yr) in
List.fold_right newlist ~init:[] ~f:(fun (a,_) r -> r :: a)
可以直接在形参中进行模式匹配,所以不用写
fun x -> match x with
| (a,_) -> a = d
你可以写:
fun (a,_) -> a = d
当代码干净时,可以更容易地找到错误。当您向右折叠时(这是 CS51,对吗?),您使用的是 cons 运算符 ::
,它需要左侧的列表元素和右侧的列表。看来你选错了方向。
您的错误来自错误使用 cons 运算符 ::
。另外,你本可以做得更好!
请注意,您的 List.fold_right
的行为与 List.map
完全相同。所以你可以使用它并且更简洁:
let filter_by_year (slist:student list) (yr:year) : name list =
let newlist = List.filter slist ~f:(fun (a,b) -> b = yr) in
List.map newlist ~f:fst
我们还可以注意到,当您只能遍历一次时,您却对列表进行了两次遍历(这次使用 fold_right
):
let filter_by_year slist yr =
List.fold_right slist ~init:[]
~f:(fun (a,b) result -> if b = yr then a::result else result )
请注意,如果你想做一个真正的应用程序,你应该使用一些其他的数据结构来避免遍历整个 "database"。