Java OCaml 的 GuardTypes 类比
Java GuardTypes analogy for OCaml
你好,Whosebug!
在Java实践中存在一些关于部分定义函数的问题。有时将错误处理与计算本身分开会很方便。我们可以使用一种称为 "Guard types" 或 "Guard decorators" 的方法。
考虑一个简单的综合示例:保护空引用。这可以借助下一个 class
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 中实现相同的 "Guard type"?我相信 OCaml 作为函数式编程语言拥有足够的抽象方法而不需要面向对象的技术。
有一个可选类型的概念,您可以在其上进行有效的模式匹配。示例:
let optional = Some 20
let value =
match optional with
| Some v -> v
| None -> 0
您可以使用抽象类型来获得相同的效果。 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".
您可以使用简单的闭包
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" *)
你好,Whosebug!
在Java实践中存在一些关于部分定义函数的问题。有时将错误处理与计算本身分开会很方便。我们可以使用一种称为 "Guard types" 或 "Guard decorators" 的方法。 考虑一个简单的综合示例:保护空引用。这可以借助下一个 class
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 中实现相同的 "Guard type"?我相信 OCaml 作为函数式编程语言拥有足够的抽象方法而不需要面向对象的技术。
有一个可选类型的概念,您可以在其上进行有效的模式匹配。示例:
let optional = Some 20
let value =
match optional with
| Some v -> v
| None -> 0
您可以使用抽象类型来获得相同的效果。 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".
您可以使用简单的闭包
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" *)