2015-09-02 30 views
1

我們如何在GADT上進行模式匹配?在這種情況下,我遇到了Bigarray的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的工作版本?

回答

4

使用小工具時,通常需要在進行通用模式匹配時添加註釋(應該在所有con一種類型的結構)。

這裏是做你想要什麼正確的方法:

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,這將是佈局類型。通過佈局上的模式匹配,您可以發現它實際上等於哪個佈局類型。

+0

此語法比我在我的搜索中找到的更好:-)謝謝! –

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 =() 
#