Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Design patterns 如何在OCAML中匹配抽象数据类型的构造函数_Design Patterns_Match_Ocaml_Abstract Data Type - Fatal编程技术网

Design patterns 如何在OCAML中匹配抽象数据类型的构造函数

Design patterns 如何在OCAML中匹配抽象数据类型的构造函数,design-patterns,match,ocaml,abstract-data-type,Design Patterns,Match,Ocaml,Abstract Data Type,1) 我有这个模块类型 module type MOD_SIG = sig type t val min val max;; 2) 我根据上面的签名创建了两个模块 module MOD_UINT8 = struct type t = int32 let min = Int32.of_int 0 let max = Int32.of_int 255 end;; module MOD_UINT32 = struct type t = int64 let min =

1) 我有这个模块类型

module type MOD_SIG = sig type t val min val max;;
2) 我根据上面的签名创建了两个模块

module MOD_UINT8 = struct 
  type t = int32 
  let min = Int32.of_int 0 
  let max = Int32.of_int 255 end;;

module MOD_UINT32 = struct 
  type t = int64 
  let min = Int64.zero 
  let max = Int64.of_int 4294967295 end ;;
3) 我创建了2个一流的模块

let uint_8 = (module MOD_UINT8:MOD_SIG);; 
let uint_32 = (module MOD_UINT32:MOD_SIG);;
4) 我想编写一个函数,该函数接受一级模块作为参数,并尝试匹配该模块中的特定值是
Int32
还是
Int64

比如

let module M=(val m:MOD_SIG) in match M.t with 
  | Int32 -> "Int32" 
  | Int64 -> "Int64"

我从@octachron那里了解到这是不可能的。虽然我只是想提出这个问题来理解,但是否有解决办法?

好吧,也许您可以在模块中添加一个函数,告诉它们的特定值是什么:

type pv = I8 | I32 | I64

module type MOD_SIG = sig 
  type t
  val min 
  val max
  val which_pv : pv
;;

module MOD_UINT8 = struct 
  type t = int32 
  let min = Int32.of_int 0 
  let max = Int32.of_int 255
  let which_pv = I8
end;;

module MOD_UINT32 = struct 
  type t = int64 
  let min = Int64.zero 
  let max = Int64.of_int 4294967295 
  let which_pv = I64
end;;

实际上,有时函数取决于
t
的确切类型,而这正是函数出现的地方。比方说,你想实现一个关于数字的模块,这些数字可以是整数、无符号整数、浮点数。。。在这种情况下,基本运算取决于确切的类型,这里最好使用函子:

module type NSig = sig
  type t
  val zero : t 
  val one : t
  val min : t
  val max : t
  val add : t -> t -> t
  val mult : t -> t -> t
end;;

module MNumb (N : NSig) = struct
  type t = N.t
  let min = N.min
  let max = N.max
  let add = N.add
  let mult = N.mult
  let rec pow t n = 
    if n = 0 then N.one
    else if n = 1 then t
    else let tt = pow t (n / 2) in
      if n mod 2 = 0 then tt else mult t tt
end;;

如您所见,要创建
pow
我需要知道
1
是如何表示的以及
mult
也是如何表示的,但是由于
pow
不是一个基本函数,所以我在函子中创建它。因此,您只需将基本类型(int8、int32、int64、float、分数…)提供给函子,然后将其提供给函子以创建更高级的函数。

您不能这样做。将代码打包到模块中并生成抽象类型的确切原因是,外部代码不能依赖于精确的实现。您可以对依赖于实现的行为进行抽象,如下所示:

module type MOD_SIG = sig
    type t
    val min : t
    val max : t
    val name : string
end

let module M = (val m:MOD_SIG) in
M.name

请使用标记工具突出显示代码块,好吗?照目前的情况,你的问题完全不可读。如果他们正确回答了你的问题,不要忘记接受答案,这会让人们知道这个问题已经解决。明白了。一般来说,你们认为第一类模更好地完成这个或函子?实际上,这取决于你们想做什么。如果你的函数是特定于你选择的类型的,我认为函子更好地实现这一点。让我更新我的答案,让您了解我所看到的更好的解决方案。因此,基本上建议是让Uint8、Uint16、Uint32和Uint64包含类型t val zero:t val one:t val min:t val max:t val add:t->t->t val mult:t->t->t,并且只使用函子向上述模块添加高级函数。然而,我想要的只是在每个模块中都有刚刚超过的值和函数,而不是像pow这样的高级函数。因此,从这个角度来看,我可以假设函子是多余的,我应该简单地使用它们自己的签名和结构创建Uint8、Uint16、Uint32、Uint64,而不是利用函子吗?是的,如果你想知道你使用的是什么类型,我想你可以试试我的第一个解决方案。