我们如何在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
的工作版本?
答案 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 = ()
#