[英]List.Fold_Left type system in Ocaml?
编写Ocaml函数list_print : string list -> unit
,从左到右打印列表中的所有字符串:
所以让我们说我有一个Ocaml函数list_print: string list -> unit
,它从左到右打印列表中的所有字符串。 现在正确的解决方案是:
let list_print lst = List.fold_left (fun ( ) -> fun s -> print_string s) () lst;;
但在编写我的解决方案时,我是这样编写的:
let list_print lst = List.fold_left (fun s -> print_string s) () lst;;
但这给了我
错误:此表达式具有类型单位,但表达式需要类型为“a - > string”
为什么在乐趣之前我需要第一个参数fun() - >? 我还是Ocaml的新手,所以这种类型的系统让我很困惑
fold_left
(和fold_right
)的目的是在你继续时积累一个值。 额外参数是此累计值。
您可以使用List.iter
来解决您的问题。 它不会累积值。
你能想到的List.iter
一个版本的List.fold_left
,其累积类型的值unit
。 事实上,你可以这样实现它:
let iter f = List.fold_left (fun () a -> f a) ()
该点(与unit
)是该类型只有一个值,因此它表示值不感兴趣的情况。
你想使用List.fold_left
,这很好,但你应该先阅读该函数的文档。 官方文档非常简短:
val fold_left : ('a -> 'b -> 'a) -> 'a -> 'b list -> 'a
List.fold_left f a [b1; ...; bn] is f (... (f (f a b1) b2) ...) bn.
第一件事是该功能的类型 。 类型是
('a -> 'b -> 'a) -> 'a -> 'b list -> 'a
换句话说,函数fold_left
有三个参数和一个结果值。 第一个参数有类型('a -> 'b -> 'a)
。 第二个参数的类型为'a
。 第三个参数有'b list
类型。 函数的结果值具有类型'a
。
现在,在您的情况下,您想要打印字符串。 所以你实际上并不需要任何结果值 ,你需要副作用。 但是,在OCaml中,所有函数都必须具有结果值。 所以你使用空值()
,它有类型unit
。 因此,在您的情况下,类型参数'a
将等于unit
。
类型参数'b
是string
因为您需要处理字符串列表。
因此,在您的情况下,函数fold_left
必须具有类型
(unit -> string -> unit) -> unit -> string list -> unit.
fold_left
的第一个参数必须具有unit->string->unit
类型。 换句话说,它必须是一个带有两个参数的函数,第一个参数是空值,即()
,第二个参数是一个字符串。 所以fold_left
的第一个参数必须是这种函数,
fun x y -> ...
其中x
必须是unit
类型, y
必须是string
类型。 由于x
将始终等于()
,因此不必将此参数写为变量x
,而是简单地写入()
甚至伪参数_
。 (语法fun x -> fun y -> ...
提供与fun xy -> ...
相同的功能fun xy -> ...
)
现在您可以开始弄清楚fold_left的工作原理了。 由于这显然是一个家庭作业问题,我将把这个任务交给你。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.