2016-03-01 12 views
1

你好,Stackoverflow!OCaml的Java GuardTypes类比

在Java实践中,存在一些与部分定义的函数有关的问题。有时将错误处理与计算本身分开很方便。我们可能会使用一种叫做“Guard类型”或“Guard装饰器”的方法。 考虑一个简单的合成示例:防止空引用。 是否有实现OCaml中同样的“锦衣卫型”不接触它的对象模型的方式:这与下一个类

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;  
} 

问题是的帮助下做了什么?我相信OCaml作为功能编程语言拥有足够的抽象方法而无需面向对象的工艺。

回答

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". 
+1

这似乎是非常的回答我找过!非常感谢! – Lionishy

1

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

let optional = Some 20 
let value = 
    match optional with 
    | Some v -> v 
    | None -> 0 
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" *) 
+0

我已经考虑过这种方法。 但是,我想声明一个类型来保护函数参数,不仅仅是懒惰的评估。 – Lionishy

+0

抽象类型可以定义一个这样的函数 'let guarded_head g_lst = head(G.take g_lst);;'它被键入为''a Gt - >'a'现在我不打扰空列表内部'guarded_head'。 'G.take'负责错误处理。例如,可以声明G.take返回'G.make'中指定的_default value_,而不是立即失败。 您还有其他想法,那么您可以善意地与我们分享。 – Lionishy