繁体   English   中英

Ocaml中的List.Fold_Left类型系统?

[英]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

类型参数'bstring因为您需要处理字符串列表。

因此,在您的情况下,函数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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM