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

Ocaml 如何在Bigarray中的GADT上进行模式匹配?,ocaml,gadt,Ocaml,Gadt,我们如何在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" 无法编译,并显示错误消息 Erro

我们如何在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\u布局
的情况。如果我们看一下
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,我对模式匹配做了一些错误的事情。
打印布局的工作版本是什么?

这里有一个函数,它返回一个表示布局的字符串:

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 = ()
#
$ocaml
OCaml版本4.02.1
##加载“bigarray.cma”;;
#开放大数组;;
#设fv=Genarray.create int32 Fortran_布局[|0;1;2 |];;
val fv:
(int32,Bigarray.int32_elt,Bigarray.fortran_布局)Bigarray.Genarray.t=
#让cv=Genarray.create int32 C|u布局[|0;1;2 |];;
val cv:(int32,Bigarray.int32_elt,Bigarray.c_布局)Bigarray.Genarray.t=
#让布局_str:类型l。l Bigarray.layout->string=函数
|Bigarray.C_布局->“C布局”
|Bigarray.Fortran_布局->“Fortran布局”;;
val layout_str:'l Bigarray.layout->string=
#让我们打印布局v=
Printf.Printf“%s\n”(layout_str(Bigarray.Genarray.layout v));;
val print_布局:('a,'b,'c)Bigarray.Genarray.t->unit=
#打印版面fv;;
Fortran布局
-:单位=()
#打印简历;;
C布局
-:单位=()
#

使用GADT,在进行泛型模式匹配时,通常需要添加注释(一个应该适用于类型的所有构造函数的注释)

以下是您想要做的事情的正确方法:

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,它将成为布局类型。通过布局上的模式匹配,您可以发现它实际上等于哪种布局类型。

此语法比我在搜索中发现的更好:-)谢谢!