如果期望,为什么不接受字符串类型?

时间:2019-05-06 18:02:37

标签: oop ocaml

我试图从here创建和使用堆栈对象(修改为具有字符串):

let s = object
    val mutable v = [""; ""]

    method pop =
      match v with
      | hd :: tl -> 
        v <- tl;
        Some hd
      | [] -> None

    method push hd = 
      v <- hd :: v
  end ;;

let () = 
    s#push "first";
    s#push "second";
    s#push "third";
    print_endline  s#pop;   (* error from this line *)
    print_endline  s#pop;
    print_endline  s#pop;

但是,我遇到以下错误:

$ ocaml objects.ml 

File "./objects.ml", line 19, characters 15-20:
Error: This expression has type string option
       but an expression was expected of type string

我无法理解错误:如果期望的类型是字符串,为什么不接受字符串类型的表达式?

1 个答案:

答案 0 :(得分:3)

  

我无法理解错误:如果期望的类型是字符串,为什么不接受字符串类型的表达式?

因为表达式s#pop的类型为string。其类型为string option,即Some sNone,其中s的类型为string

看一下pop方法的实现,如果堆栈中有更多元素等待,则返回Some s;如果堆栈为空,则返回None

method pop =
  match v with
  | hd :: tl -> 
    v <- tl;
    Some hd  (* returns `Some hd` *)
  | [] -> None (* returns `None` *)

您可以实现一个辅助函数,该函数将打印string option类型的值,例如

 let print_some s = match s with
   | None -> print_endline "empty"
   | Some s -> print_endline s

使用方法

let () =
  s#push "first";
  s#push "second";
  s#push "third";
  print_some  s#pop; 
  print_some  s#pop;
  print_some  s#pop;

这里是stack对象的一些替代实现,它们使用其他方式与调用方进行通信,以告知栈为空,例如,来自栈元素域(由用户提供)的哨兵值,异常或result类型,并带有字符串错误的参数。

let stack_with_sentinel empty = object
    val mutable v = []
    method pop = match v with
      | hd :: tl -> 
        v <- tl;
        hd
      | [] -> empty
  end

let stack_with_exception = object
    val mutable v = []
    method pop = match v with
      | hd :: tl -> 
        v <- tl;
        hd
      | [] -> raise Not_found
  end

let stack_with_result = object
    val mutable v = []
    method pop = match v with
      | hd :: tl -> 
        v <- tl;
        Ok hd
      | [] -> Error "empty stack"
  end 

还有许多其他方法来定义它,但是最常用的是使用option类型。