OCaml函数中的新构造函数

时间:2015-04-17 07:45:10

标签: ocaml

编写此功能时:

let make_new_instance class_name = new class_name

我得到错误“unbound class class_name”,但是,这只是一个函数定义,而不是函数调用。如何延迟“new”以便在调用函数之前不会尝试构造对象?

5 个答案:

答案 0 :(得分:4)

你不能在OCaml中这样做,OCaml是一种静态类型的语言。必须在new静态指定类,并且不能将其用作函数应用程序的参数。 (new甚至不是一个函数,而是一个特殊形式new <classname>。)

参数化类的一种方法是使用仿函数:

module A = struct
  class c = object
    method x = 1
  end
end

module Make(A : sig class c : object method x : int end end) = struct
  let make_new_instance () = new A.c
end

module MakeA = Make(A)

但我担心这远不是你想要的。

答案 1 :(得分:1)

这不是你在OCaml中可以做的事情。一种看待这种情况的方法是考虑将传递给函数的内容。类名是类型,而不是值。另一种方法是注意函数只能返回一种类型的值。不同的类有不同的类型。

答案 2 :(得分:0)

您是否尝试将class_name参数更改为单位?

let make_new_class_name () = new class_name

答案 3 :(得分:0)

OCaml中的类似蓝图,但是为了创建某些东西,通常不是从蓝图开始,而是去工厂。因此,如果您需要一个创建某个类实例的工厂,那么就可以完成:

class blue_print x y = object ... end
let create_instance = new blue_print
let factory instance_maker x y = instance_maker x y

当然,所有这些都没有多大意义,因为示例非常简单,但如果它与某些注册表相关联,那么您将存储instace_maker s,那么您将获得一个抽象工厂< / p>

答案 4 :(得分:0)

  

我收到错误unbound class class_name,但这只是一个函数定义,而不是函数调用。如何延迟&#34; new&#34;这样在调用函数之前它不会尝试构造一个对象吗?

你得到的错误来自class_name这里是函数参数的名称这一事实,但你试着让它带有一个类的名字。在PERL,PHP或其他类似语言的语言中,您可以在运行时访问符号表,从而可以定义新函数,新类,新变量,并在变量中引用它们。例如,在PHP中,代码为:

 <?php

    function foo($var){ echo ${$var};}

    $bar = "foo";
    $bar($bar);

会呈现:

 "Function"

通过变量foo调用函数$bar

在OCaml中,您无法使用值名称执行此操作,在您的确切情况下,语法严格要求在关键字new之后使用类名称(否则您将遇到动态语言中通常遇到的问题,即,如何检查变量内容是否真的是一个类) - 杰弗里Scoffield就在那里。但是,作为一种函数式语言,通常的方法是传递函数,并将它们应用于其他函数中的参数:

class foo () = object
  method m = "foo"
end

class bar () = object
  method m = "bar"
end

上面的两个类都有相同的类类型,并且期望使用相同的参数来创建它们的实例,因此您可以互换使用它们而不输入问题。

let mk_instance toggle : object method m : string end = 
  if toggle 
  then new foo ()
  else new bar ()

函数mk_instance将生成foo的实例或bar的实例,具体取决于toggle的值。

您可以通过创建包含foobar s实例化的函数来使用它,然后传递它们:

let mk_foo = new foo
let mk_bar = new bar

let mk_instance mk : object method m : string end = mk ()

上面的内容很简单,但您可能会设想具有更多相关类定义的案例,并且通过闭包,始终可以对齐函数签名以使其更容易,或者将它们嵌入到求和类型中以指示不同的可能性。