编辑: 虽然这个答案具有理论价值,但您现在想阅读neo's answer。
对于某些类型t,定义一个模块,
module type Semigroup = sig
type t
val add : t -> t -> t
end
还有一些实用函数,例如 partialsums,它们依赖于函子内部的 this,
module Utils (S : Semigroup) = struct
let partialsums xs =
match xs with
| [] -> []
| (x::xs) ->
List.rev (snd (List.fold_left
(fun (acc, ys) x -> let y = S.add acc x in (y, y::ys)) (x, [x]) xs))
end
您可以获得专门针对特定类型的partialsumst,
module IntUtils = Utils(struct type t = int
let add = (+) end)
module FloatUtils = Utils(struct type t = float
let add = (+.) end)
let int_test = IntUtils.partialsums [1; 2; 3; 4] ;;
let float_test = FloatUtils.partialsums [1.0; 2.0; 3.0; 4.0]
这很酷,但也有点乏味;你仍然必须在你的函数前面加上一些特定类型的东西,但至少你只需要编写一次函数。这只是模块系统很棒。
使用模块化隐式,是的,是的,是的!
使用 White、Bour 和 Yallop 的 Modular Implicits (2014),您可以写作,
implicit module Semigroup_int =
type t = int
let add = (+)
end
implicit module Semigroup_float =
type t = float
let add = (+.)
end
implicit module Semigroup_string =
type t = string
let add = (^)
end
let add {S : Semigroup} x y = S.add x y
这将允许定义一个泛型和重载partialsums,
let partialsums xs =
match xs with
| [] -> []
| (x::xs) ->
List.rev (snd (List.fold_left
(fun (acc, ys) x -> let y = add acc x in (y, y::ys)) (x, [x]) xs))
所以现在它同样适用于整数和浮点数!
let int_test = partialsums [1; 2; 3; 4] ;;
let float_test = partialsums [1.0; 2.0; 3.0; 4.0]
let string_test = partialsums ["a"; "b"; "c"; "d"]
在统一 ML 模块系统和 Haskell 的类型类概念方面显然已经进行了几次尝试。参见例如Modular Type Classes (2007) 由 Dreyer、Harper 和 Chakravarty 撰写,提供了一个很好的背景故事。