OCaml 中的经典单例实现

发布于 2024-07-14 00:10:28 字数 381 浏览 6 评论 0原文

我正在尝试在 OCaml 中概念化单例设计模式(qua Java),并且看到过任何暗示函子或模块的实例,而我在 GoF 工作的概念证明中都没有使用它们。 基本上,我想使用 OCaml 重新创建以下功能:

public class Singleton
{
 private static Singleton UniqueInstance; 
 private Singleton(){}
 public static Singleton getInstance()
 {
  if(UniqueInstance==null)UniqueInstance=new Singleton();
  return UniqueInstance;
 }
}

如果没有模块或函子,这可能吗?

I am attempting to conceptualize the Singleton design pattern (qua Java) in OCaml and have seen ever instance allude to functors or modules, neither of which I am using in a proof of concept of GoF's work. Basically, I would like to recreate the following functionality using OCaml:

public class Singleton
{
 private static Singleton UniqueInstance; 
 private Singleton(){}
 public static Singleton getInstance()
 {
  if(UniqueInstance==null)UniqueInstance=new Singleton();
  return UniqueInstance;
 }
}

Is this possible without modules or functors?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

话少心凉 2024-07-21 00:10:28

您能否解释一下为什么该模块解决方案不适合您? 模块确实是在其他语言中使用单例进行操作的自然方法。

一般来说,GOF 风格的模式在 OCaml 中很大程度上是无关紧要的。 事实上,对象在 OCaml 中很大程度上是无关紧要的。 有 OO 背景的人通常认为他们应该从使用 OCaml 中的 OO 功能开始,但这是一个错误。 使用其他语言中的对象解决的大多数问题都可以通过 OCaml 中的参数多态性、代数数据类型和模块来解决。 函子是一个稍微高级的话题,而对象则很遥远。 在您成为该语言其余部分的熟练用户之前,您不应该接触对象系统。

Can you explain why the module solution doesn't work for you? Modules really are the natural way to do what you would do with a singleton in other languages.

As a general matter, GOF-style patterns are largely irrelevant in OCaml. Indeed, objects are largely irrelevant in OCaml. People from OO backgrounds often think they should start out by using the OO features in OCaml, but this is a mistake. Most problems that are solved with objects in other languages are solved with parametric polymorphism, algebraic datatypes and modules in OCaml. Functors are a slightly more advanced topic, and objects are way out there. You shouldn't touch the object system until you are an accomplished user of the rest of the language.

最偏执的依靠 2024-07-21 00:10:28

Ocaml 中的对象不能有静态/全局方法。 您可以尝试立即对象 。 警告,我认为您仍然可以执行 obj.copy 来获取对象的副本,并且每次评估它们时,它们都会返回一个新对象(因此您不能将参数传递给对象,但是可以,通过一些封装和全局布尔值,但现在您正在处理模块)。 当然,如果您只有类似示例的内容,则

let p = object 
   val mutable x = 0
   method get_x = x
   method move d = x <- x + d
end

p 将被评估一次,并且您每次都会访问它。 当然,p#copy 会让你把事情搞砸。 模块是解决这个问题的方法。 Ocaml 的面向对象功能并不像其他语言那样“强大”。 这当然不是该项目的目标,它的模块系统非常强大。

模块(全局)单例。 您实际上不需要编写任何内容来构建它们。 它们隐含在语言中。 例如,如何记录到文件:

---logging.ml
(* default channel to log *)
let log_channel = ref stdout

(* set the log to a channel *)
let set_log_chan chan = log_channel := chan

(* timestamp of log -- kinda heavy weight, but just for kicks *)
let get_log_prequel () = 
    let time = Unix.localtime (Unix.time ()) in
    (* format the time data into "y/m/d - h:m:s" format *)
    Printf.sprintf  "%d/%02d/%02d - %02d:%02d:%02d"
                    (time.Unix.tm_year+1900) time.Unix.tm_mon time.Unix.tm_mday
                    time.Unix.tm_hour time.Unix.tm_min time.Unix.tm_sec

(* log a string to the channel *)
let log_string str =
    output_string (!log_channel) ((get_log_prequel ())^":\t"^str^"\n")

---logging.mli
set_log_chan : in_channel -> unit
log_string : string -> unit

我想您已经明白了这一点。 单例是隐式的,对吗? 确实没有像对象那样的实例化——但这正是您在单例中想要的。 您只需开始在其他文件中使用它,例如 Logging.log_string "parsed file "^file_name^" success." 等,在任何地方,您始终使用相同的通道。

使用函子,您可以组合模块以增加多样性。 就像指定一个模块/函数来生成输出的前传等等。

Objects in Ocaml can not have static / global methods. You can try, Immediate objects. Caveat, I think you can still do obj.copy to get a copy of the object, and every time they are evaluated they return a new object (so you cannot pass parameters to the object, well you can, with some encapsulation and a global boolean, but now you're dealing with modules). Of course, if you only have something like there example,

let p = object 
   val mutable x = 0
   method get_x = x
   method move d = x <- x + d
end

p would be evaluated once, and you would access that each time. Of course, p#copy would mess things up for you. Modules are the way to go here. Ocaml's OO features aren't as 'powerful' as other languages. It's of course not the goal of the project, it's module system is very powerful.

Modules are (global) singletons. There really isn't anything you have to write to build them. They are implicitly in the language. For example, how about logging to a file:

---logging.ml
(* default channel to log *)
let log_channel = ref stdout

(* set the log to a channel *)
let set_log_chan chan = log_channel := chan

(* timestamp of log -- kinda heavy weight, but just for kicks *)
let get_log_prequel () = 
    let time = Unix.localtime (Unix.time ()) in
    (* format the time data into "y/m/d - h:m:s" format *)
    Printf.sprintf  "%d/%02d/%02d - %02d:%02d:%02d"
                    (time.Unix.tm_year+1900) time.Unix.tm_mon time.Unix.tm_mday
                    time.Unix.tm_hour time.Unix.tm_min time.Unix.tm_sec

(* log a string to the channel *)
let log_string str =
    output_string (!log_channel) ((get_log_prequel ())^":\t"^str^"\n")

---logging.mli
set_log_chan : in_channel -> unit
log_string : string -> unit

I think you get the point here. The singleton is implicit, right? There really isn't an instantiation like in objects --but that's kinda what you want in a singleton. You just start using it in other files like, Logging.log_string "parsed file "^file_name^" successfully.", et cetera, anywhere and you always use the same channel.

With functors you can compose your modules to add variety. Like specifying a module/function to generate a prequel for output, et cetera.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文