Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/drupal/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ocaml 函子-导入类型_Ocaml - Fatal编程技术网

Ocaml 函子-导入类型

Ocaml 函子-导入类型,ocaml,Ocaml,我是OCaml新手,正在努力学习函子。到目前为止,我有以下几点: utop # module type Foo = sig type t = { foo : int; bar : int; } val create : int -> int -> t val get : t -> int end;; utop # module FooImpl = struct type t = { foo : int; ba

我是OCaml新手,正在努力学习函子。到目前为止,我有以下几点:

utop # module type Foo = sig
  type t = {
      foo : int;
      bar : int;
  }
  val create : int -> int -> t
  val get : t -> int
end;;

utop # module FooImpl = struct
  type t = {
      foo : int;
      bar : int;
  }
  let create x y = {
      foo = x;
      bar = y;
  }
  let get w = w.foo
end;;
现在我将尝试定义我的functor,它将对Foo类型的模块进行操作,并替换
get
函数

utop # module Functor (F : Foo) : Foo with type t := F.t = struct
  let create = F.create
  let get w = w.bar
end;;
Error: Unbound record field bar
它不知道记录的类型。我将尝试定义它:

utop # module Functor (F : Foo) : Foo with type t := F.t = struct
  type t = {
      foo : int;
      bar : int;
  }
  let create = F.create
  let get w = w.bar
end;;
Error: Signature mismatch:                                                                                                                ...                                                                                                                                Values do not match:
     val get : t -> int
   is not included in
     val get : F.t -> int
所以OCaml不知道
t
F.t
实际上是同一类型。所以我试着说:

utop # module Functor (F : Foo) : Foo with type t := F.t = struct
  type t = F.t
  let create = F.create
  let get w = w.bar
end;;
Error: Unbound record field bar

我做错了什么?

如果我这样定义
get
,那么你第一次尝试定义Functor对我来说是有效的:

let get w = w.F.bar
以下是我的全部课程:

# module type Foo = sig (... ELIDED...) end;;
module type Foo =
  sig
    type t = { foo : int; bar : int; }
    val create : int -> int -> t
    val get : t -> int
  end
# module FooImpl = struct (...ELIDED...) end;;
module FooImpl :
  sig
    type t = { foo : int; bar : int; }
    val create : int -> int -> t 
    val get : t -> int
  end
# module Functor (F: Foo) : Foo with type t := F.t = struct 
    let create = F.create 
    let get w = w.F.bar 
end;;
module Functor :
  functor (F : Foo) ->
    sig val create : int -> int -> F.t val get : F.t -> int end
# module F2 = Functor(FooImpl);;
module F2 :
  sig val create : int -> int -> FooImpl.t val get : FooImpl.t -> int end
# let c1 = FooImpl.create 8 9;;
val c1 : FooImpl.t = {FooImpl.foo = 8; bar = 9}
# FooImpl.get c1;;
- : int = 8
# let c2 = F2.create 8 9;;
val c2 : FooImpl.t = {FooImpl.foo = 8; bar = 9}
# F2.get c2;;
- : int = 9

如果我这样定义
get
,那么您第一次尝试定义Functor对我来说是有效的:

let get w = w.F.bar
以下是我的全部课程:

# module type Foo = sig (... ELIDED...) end;;
module type Foo =
  sig
    type t = { foo : int; bar : int; }
    val create : int -> int -> t
    val get : t -> int
  end
# module FooImpl = struct (...ELIDED...) end;;
module FooImpl :
  sig
    type t = { foo : int; bar : int; }
    val create : int -> int -> t 
    val get : t -> int
  end
# module Functor (F: Foo) : Foo with type t := F.t = struct 
    let create = F.create 
    let get w = w.F.bar 
end;;
module Functor :
  functor (F : Foo) ->
    sig val create : int -> int -> F.t val get : F.t -> int end
# module F2 = Functor(FooImpl);;
module F2 :
  sig val create : int -> int -> FooImpl.t val get : FooImpl.t -> int end
# let c1 = FooImpl.create 8 9;;
val c1 : FooImpl.t = {FooImpl.foo = 8; bar = 9}
# FooImpl.get c1;;
- : int = 8
# let c2 = F2.create 8 9;;
val c2 : FooImpl.t = {FooImpl.foo = 8; bar = 9}
# F2.get c2;;
- : int = 9

字段名属于定义它们的模块的范围。例如,如果在模块
Foo

module Foo = struct
  type t = { bar : int; baz : int; quz : int }
end
然后,为了访问模块
Foo
之外的字段,您需要使用完全限定的名称,例如

let bar_of_foo x = x.Foo.bar
在模式匹配中,字段名称也可能是限定的,这允许按如下方式编写上述函数:

let bar_of_foo {Foo.bar} = bar
您只需要限定一个名称,因此当您需要同时访问多个字段时,此语法非常有用:

let sum_of_foo {Foo.bar; baz; quz} = bar + baz + quz
最后,您可以
打开
模块,将记录名称带到当前范围。您可以使用本地打开语法
Foo.(expr)
来本地化打开的影响:

 let bar_of_foo x = Foo.(x.bar) 
在您的示例中,字段在模块
F
中定义,该模块是函子
函子的参数。因此,您需要使用上述方法之一来访问it字段,例如

module Functor (F : Foo) : Foo with type t := F.t = struct
 open F
 let create = F.create
 let get w = w.bar
end

字段名属于定义它们的模块的范围。例如,如果在模块
Foo

module Foo = struct
  type t = { bar : int; baz : int; quz : int }
end
然后,为了访问模块
Foo
之外的字段,您需要使用完全限定的名称,例如

let bar_of_foo x = x.Foo.bar
在模式匹配中,字段名称也可能是限定的,这允许按如下方式编写上述函数:

let bar_of_foo {Foo.bar} = bar
您只需要限定一个名称,因此当您需要同时访问多个字段时,此语法非常有用:

let sum_of_foo {Foo.bar; baz; quz} = bar + baz + quz
最后,您可以
打开
模块,将记录名称带到当前范围。您可以使用本地打开语法
Foo.(expr)
来本地化打开的影响:

 let bar_of_foo x = Foo.(x.bar) 
在您的示例中,字段在模块
F
中定义,该模块是函子
函子的参数。因此,您需要使用上述方法之一来访问it字段,例如

module Functor (F : Foo) : Foo with type t := F.t = struct
 open F
 let create = F.create
 let get w = w.bar
end