types - 具有参数类型的第一类模块(类型构造函数 F.f 将逃脱其范围)

标签 types module ocaml locally-abstract-type

我目前正在使用模块,看看它们可以以与 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)

但这看起来增加了很多复杂性,因为这可能应该更简单。

最佳答案

使用上面提到的论文中的想法(假设您已经定义了 appNewtype1 如论文中所述或使用他们的 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/

相关文章:

ocaml - 如何访问 OCaml 中的对象字段?

Python 帮助 - 属性错误 : 'module' object has no attribute 'ArgumentParser'

import - 第三方库上的 Rust `unresolved import`

python - get_num_instances 引发 InvalidVersionError

c# - 从 PropertyInfo[] 获取值时如何传递正确的目标

ocaml - 如何在 OCaml 中定义 int64?

ocaml - OCaml最近几年有没有获得任何严重晋升?

java - Apache 节俭,Java : Object Data Types

haskell - Haskell 是否支持封闭的多态类型?

c++ - 如何在C++中获取变量的类型