OCaml 中 Return 个不同的前 class 个模块
Return different first class modules in OCaml
我想 return 来自一个函数的不同模块。这是我希望可行的总体思路。
module type First = sig
val speak : unit -> unit
end
module First = struct
let speak () = print_endline "hi"
end
module type Second = sig
val another_speaker : unit -> unit
end
module Second = struct
let another_speaker () = print_endline "another hi"
end
type mods = First | Second
let load = function
| First -> (module First : First)
| Second -> (module Second : Second)
1) 但这不是因为加载的 return 类型在第一次匹配时就确定了。我怎样才能使这个总体想法可行?
2) 我怎样才能写出这样的东西并让它发挥作用。
type a = [`First of (module type First )]
您不能将这两种模块类型视为同一类型,因为它们是不同的。但是你可以将它们组合成一个变体类型。
这对我有用:
module type First = sig
val speak : unit -> unit
end
module type Second = sig
val another_speaker : unit -> unit
end
type modvar = MFirst of (module First) | MSecond of (module Second)
type mods = First | Second
module First = struct
let speak () = print_endline "hi"
end
module Second = struct
let another_speaker () = print_endline "another hi"
end
let load = function
| First -> MFirst (module First)
| Second -> MSecond (module Second)
我不确定这是否是您要找的。
更新
下面是使用多态变体重写的相同代码:
module type First = sig
val speak : unit -> unit
end
module type Second = sig
val another_speaker : unit -> unit
end
type mods = First | Second
module First = struct
let speak () = print_endline "hi"
end
module Second = struct
let another_speaker () = print_endline "another hi"
end
let load = function
| First -> `MFirst (module First: First)
| Second ->`MSecond (module Second: Second)
关键是你需要标记load
返回的值。否则它们必须是同一类型,但它们不是。
"good"解决方案是为每个人使用相同的模块类型:
module type S = sig
val speak : unit -> unit
end
module First = struct
let speak () = print_endline "hi"
end
module Second = struct
let speak () = print_endline "another hi"
end
type mods = First | Second
let load = function
| First -> (module First : S)
| Second -> (module Second : S)
实在不行的话,除了Jeffrey给出的变种方案,还有GADT方案:
type 'a t = First : (module First) t | Second : (module Second) t
let load : type a . a t -> a = function
| First -> (module First : First)
| Second -> (module Second : Second)
我想 return 来自一个函数的不同模块。这是我希望可行的总体思路。
module type First = sig
val speak : unit -> unit
end
module First = struct
let speak () = print_endline "hi"
end
module type Second = sig
val another_speaker : unit -> unit
end
module Second = struct
let another_speaker () = print_endline "another hi"
end
type mods = First | Second
let load = function
| First -> (module First : First)
| Second -> (module Second : Second)
1) 但这不是因为加载的 return 类型在第一次匹配时就确定了。我怎样才能使这个总体想法可行?
2) 我怎样才能写出这样的东西并让它发挥作用。
type a = [`First of (module type First )]
您不能将这两种模块类型视为同一类型,因为它们是不同的。但是你可以将它们组合成一个变体类型。
这对我有用:
module type First = sig
val speak : unit -> unit
end
module type Second = sig
val another_speaker : unit -> unit
end
type modvar = MFirst of (module First) | MSecond of (module Second)
type mods = First | Second
module First = struct
let speak () = print_endline "hi"
end
module Second = struct
let another_speaker () = print_endline "another hi"
end
let load = function
| First -> MFirst (module First)
| Second -> MSecond (module Second)
我不确定这是否是您要找的。
更新
下面是使用多态变体重写的相同代码:
module type First = sig
val speak : unit -> unit
end
module type Second = sig
val another_speaker : unit -> unit
end
type mods = First | Second
module First = struct
let speak () = print_endline "hi"
end
module Second = struct
let another_speaker () = print_endline "another hi"
end
let load = function
| First -> `MFirst (module First: First)
| Second ->`MSecond (module Second: Second)
关键是你需要标记load
返回的值。否则它们必须是同一类型,但它们不是。
"good"解决方案是为每个人使用相同的模块类型:
module type S = sig
val speak : unit -> unit
end
module First = struct
let speak () = print_endline "hi"
end
module Second = struct
let speak () = print_endline "another hi"
end
type mods = First | Second
let load = function
| First -> (module First : S)
| Second -> (module Second : S)
实在不行的话,除了Jeffrey给出的变种方案,还有GADT方案:
type 'a t = First : (module First) t | Second : (module Second) t
let load : type a . a t -> a = function
| First -> (module First : First)
| Second -> (module Second : Second)