如何在Bigarray的GADT上进行模式匹配?

时间:2015-09-02 05:17:07

标签: ocaml gadt

我们如何在GADT上进行模式匹配?在这种情况下,我遇到了Bigarray的GADT问题。更具体地说,代码

let print_layout v = match Bigarray.Genarray.layout v with
    | Bigarray.C_layout -> Printf.printf "C layout\n"
    | Bigarray.Fortran_layout -> Printf.printf "Fortran layout\n"

无法编译并显示错误消息

Error: This pattern matches values of type
         Bigarray.fortran_layout Bigarray.layout
       but a pattern was expected which matches values of type
         Bigarray.c_layout Bigarray.layout
       Type Bigarray.fortran_layout is not compatible with type
         Bigarray.c_layout 

它抱怨Bigarray.Fortran_layout案件。如果我们查看Bigarray,我们会看到

type c_layout = C_layout_typ
type fortran_layout = Fortran_layout_typ
type 'a layout =
    C_layout : c_layout layout
  | Fortran_layout : fortran_layout layout

所以,它是一个GADT,我在模式匹配方面做错了。什么是print_layout的工作版本?

2 个答案:

答案 0 :(得分:5)

使用小工具时,通常需要在执行通用模式匹配时添加注释(一个应该适用于某种类型的所有构造函数)。

这是做你想做的正确方法:

let print_layout (type t) (v: (_,_,t) Bigarray.Genarray.t) =
  match Bigarray.Genarray.layout v with
  | Bigarray.C_layout -> Printf.printf "C layout\n"
  | Bigarray.Fortran_layout -> Printf.printf "Fortran layout\n"

注释引入了一个抽象类型t,它将是布局类型。通过布局上的模式匹配,您可以发现它实际上等于哪种布局类型。

答案 1 :(得分:1)

这是一个返回表示布局的字符串的函数:

let layout_str : type l. l Bigarray.layout -> string = function
  | Bigarray.C_layout -> "C layout"
  | Bigarray.Fortran_layout -> "Fortran layout"

您可以使用它来定义所需的功能

let print_layout v =
  Printf.printf "%s\n" (layout_str (Bigarray.Genarray.layout v))

它对我有用:

$ ocaml
        OCaml version 4.02.1

# #load "bigarray.cma";;
# open Bigarray;;
# let fv = Genarray.create int32 Fortran_layout [| 0; 1; 2 |];;
val fv :
  (int32, Bigarray.int32_elt, Bigarray.fortran_layout) Bigarray.Genarray.t =
  <abstr>
# let cv = Genarray.create int32 C_layout [| 0; 1; 2 |];;
val cv : (int32, Bigarray.int32_elt, Bigarray.c_layout) Bigarray.Genarray.t = 
  <abstr>
# let layout_str : type l. l Bigarray.layout -> string = function
  | Bigarray.C_layout -> "C layout" 
  | Bigarray.Fortran_layout -> "Fortran layout";;
val layout_str : 'l Bigarray.layout -> string = <fun>
# let print_layout v =
  Printf.printf "%s\n" (layout_str (Bigarray.Genarray.layout v));;
val print_layout : ('a, 'b, 'c) Bigarray.Genarray.t -> unit = <fun>
# print_layout fv;;
Fortran layout
- : unit = ()
# print_layout cv;;
C layout
- : unit = ()
#
相关问题