Java GuardType类似于OCaml

时间:2016-03-01 08:24:14

标签: ocaml

你是怎么做的,Stackoverflow!

在Java实践中,存在一些与部分定义的函数有关的问题。有时将错误处理与计算本身分开是很方便的。我们可以使用一种名为" Guard类型"或"警卫装饰"。 考虑简单的合成示例:保护空引用。这可以借助下一课

来完成
public class NonNull<T> {
    public take() {
        return null != this.ref ? this.ref : throw new ExcptionOfMine("message");
    }

    public NotNull(T ref_) {
        this.ref     = ref_;
    }

    private T ref;       
}

问题是: 有没有办法实现相同的&#34; Guard类型&#34;在OCaml中没有触及它的对象模型?我相信OCaml作为函数式编程语言,拥有足够的抽象方法而没有面向对象的技术。

3 个答案:

答案 0 :(得分:1)

有一个可选类型的概念,您可以在其上有效地模式匹配。例如:

let optional = Some 20
let value = 
  match optional with
  | Some v -> v
  | None -> 0

答案 1 :(得分:1)

您可以使用抽象类型来获得相同的效果。 OCaml对空指针没有问题。所以说你想要以与上面相同的方式表示非空列表。即,您希望能够创建空的值,但只有在该人试图访问该值时才会抱怨。

module G :
sig type 'a t 
    val make : 'a list -> 'a t 
    val take : 'a t -> 'a list 
end =
struct
    type 'a t = 'a list
    let make x = x
    let take x = if x = [] then raise (Invalid_argument "take") else x
end

以下是使用模块时的外观:

$ ocaml
        OCaml version 4.02.1

# #use "m.ml";;
module G :
  sig type 'a t val make : 'a list -> 'a t val take : 'a t -> 'a list end
# let x = G.make [4];;
val x : int G.t = <abstr>
# G.take x;;
- : int list = [4]
# let y = G.make [];;
val y : '_a G.t = <abstr>
# G.take y;;
Exception: Invalid_argument "take".

答案 2 :(得分:1)

您可以使用简单的闭包

let guard_list v =
  fun () ->
    if v = [] then failwith "Empty list"
    else v

let () =
  let a = guard_list [1;2;3] in
  let b = guard_list [] in
  print_int (List.length (a ()));  (* prints 3 *)
  print_int (List.length (b ()))   (* throws Failure "Empty list" *)

或懒惰值

let guard_string v = lazy begin
  if v = "" then failwith "Empty string"
  else v
end

let () =
  let a = guard_string "Foo" in
  let b = guard_string "" in
  print_endline (Lazy.force a);  (* prints "Foo" *)
  print_endline (Lazy.force b)   (* throws Failure "Empty string" *)