我想从函数中返回不同的模块。这是我希望工作的一般概念。
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)但它没有,因为在第一场比赛中确定了负荷的回归类型。我怎样才能使这个总体思路发挥作用?
2)我怎样才能写出这样的东西并让它发挥作用。
type a = [`First of (module type First )]
答案 0 :(得分:3)
您不能将两种模块类型视为相同类型,因为它们不同。但是你可以将它们组合成一种变体类型。
这对我有用:
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
返回的值。否则它们必须是相同的类型,它们不是。
答案 1 :(得分:3)
“好”的解决方案是为每个人使用相同的模块类型:
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)