我目前正在使用模块,看看它们可以以与 Haskell 类型类类似的方式使用。目前我正在尝试使用仿函数类型类:
module type Functor =
sig
type 'a f
val fmap : ('a -> 'b) -> ('a f -> 'b f)
end
module IdFunc =
struct
type 'a f = Id of 'a
let fmap f = fun (Id a) -> Id (f a)
let runId (Id a) = a
end
let outmap (module F : Functor) av = F.fmap f av
但是在这种情况下
outmap
将无法正确键入,编译器会产生错误 The type constructor F.f would escape its scope
.我知道为什么在这种情况下会导致此错误,但我不确定如何解决它(因为类型 f 已参数化)。我已经尝试使用本地抽象类型:
let outmap (type s) (module F : Functor with type 'a f = s) f av = F.fmap f av
或者
let outmap (type a) (type b) (type fa) (type fb)
(module F : Functor with type a f = fa type b f = fb) f av =
F.fmap f av
或者
let outmap (type s) (module F : Functor with type f = s) f av = F.fmap f av
这一切都只是给我各种语法错误或打字错误。
有没有办法解决这个问题?
在 Haskell 中,这只是:
outmap : Functor f => (a -> b) -> f a -> f b
ocaml 中的等价物(如果有的话)是什么?
==== 编辑 ====
我找到了一种类似于工作的方法:
module type Functor =
sig
type a
type b
type af
type bf
val fmap : (a -> b) -> (af -> bf)
end
module type FromTo =
sig
type a
type b
end
module IdFunc =
functor (FT : FromTo) ->
struct
type a = FT.a
type b = FT.b
type 'a f = Id of 'a
type af = a f
type bf = b f
let fmap f = fun (Id a) -> Id (f a)
let runId (Id a) = a
end
let outmap (type a') (type b') (type af') (type bf')
(module F : Functor
with type a = a' and
type b = b' and
type af = af' and
type bf = bf')
f av = F.fmap f av
module M = IdFunc(struct type a = int type b = string end)
let oi = outmap (module M)
let test = oi (fun _ -> "Test") (M.Id 10)
但这看起来增加了很多复杂性,因为这可能应该更简单。
最佳答案
使用上面提到的论文中的想法(假设您已经定义了 app
和 Newtype1
如论文中所述或使用他们的 higher
来自 opam 的包),您可以将仿函数定义为:
module type Functor = sig
type t
val fmap : ('a -> 'b) -> ('a, t) app -> ('b, t) app
end
module Id = Newtype1(struct type 'a t = 'a end)
module IdFunc : Functor with type t = Id.t = struct
type t = Id.t
let fmap f x = x |> Id.prj |> f |> Id.inj
end
let runId (x : ('a, Id.t) app) : 'a = Id.prj x
let outmap (type a)
(module F : Functor with type t = a)
f av =
F.fmap f av
更多示例,您可以查看 https://github.com/hongchangwu/ocaml-type-classes
关于types - 具有参数类型的第一类模块(类型构造函数 F.f 将逃脱其范围),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24385794/