gpt4 book ai didi

generics - OCaml 中的参数化

转载 作者:行者123 更新时间:2023-12-02 19:44:09 26 4
gpt4 key购买 nike

我是 OCaml 的初学者,但我不断在介绍性示例中看到类似于以下内容的代码

let sum = List.fold ~f:(+.) ~init:0.0

这段代码中令我困扰的是 List.fold 的显式使用。在我所知道的大多数语言中,容器的显式类型将通过使用接口(interface)、特征或类型类来抽象,以便可以重用此代码来对数组或任何其他顺序容器求和。

OCaml 的方法是什么来使其更通用?

最佳答案

更通用的解决方案是使用仿函数:

module type Foldable = sig 
type 'a t
val fold : 'a t -> init:'b -> f:('b -> 'a -> 'b) -> 'b
end

module MakeSum(Container : Foldable) = struct
let sum xs = Container.fold ~f:(+.) ~init:0.0
end

正如您可能注意到的,这种额外的参数性会带来巨大的语法开销。事实上,我们可以重用 Core 中的接口(interface)来减少它:

module MakeSum(Container : Container.T) = struct
let sum xs = Container.fold ~f:(+.) ~init:0.0
end

module MakeSum(Container : Container.S1) = struct
let sum xs = Container.fold ~f:(+.) ~init:0.0
end

此外,作为示例,您可能最感兴趣的不是对容器类型的参数化,而是对求和操作和零值的参数化。这个特定的示例是使用 OCaml Core 库中的第一类仿函数(另一个选项)实现的,每个容器都实现此函数:

  (** Returns the sum of [f i] for i in the container *)
val sum
: (module Commutative_group.S with type t = 'sum)
-> t -> f:(elt -> 'sum) -> 'sum

更新

事实上,在您的特定情况下,即使没有仿函数,我们也可以进行概括,因为您不需要知道类型来实现您的代码。所以我们可以将通用 sum 定义为:

let sum fold xs = fold ~f:(+.) ~init:0.0

关于generics - OCaml 中的参数化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26960264/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com