我从this question了解到可以使用模式匹配记录。但是,我注意到我在尝试匹配不同类型的记录时遇到了麻烦。
我在这个例子中的目标是能够区分不同的记录。我给出了一个记录,我不完全确定它是哪种类型,我试图用模式匹配来解决它。
这是一个简化的例子:
https://www.npmjs.com/package/viz.js
当我尝试构建此文件时,我得到:
module IceCream = struct
type t = {
temperature: float;
toppings: string list;
}
end
module Candy = struct
type t = {
flavour: string;
colour: string;
volume: int;
}
end
(* Could be Candy or IceCream *)
let example =
{ Candy.
flavour = "mint";
colour = "green";
volume = 10 }
let printFavoriteTreat treat = match treat with
| { Candy.
flavour = "mint";
colour;
volume } -> "It's Candy"
| { IceCream.
temperature;
toppings } -> "It's IceCream"
let () = printFavoriteTreat example
这样做的可能吗?
答案 0 :(得分:3)
皮埃尔提供的答案很棒,但这个例子并不多。 (我一直讨厌名为a
,b
...)
所以,正如皮埃尔建议的那样,你可以像这样定义你的类型:
type ice_cream = {
temperature: float;
toppings: string
}
type candy = {
flavor: string;
color: string;
volume: int
}
然后,您可以将类型treat
定义为这两种类型的variant:
type treat =
| Candy of candy
| IceCream of ice_cream
然后,使用模式匹配:
let print_favorite_treat = function
| Candy _ -> print_endline "You love candy!"
| IceCream _ -> print_endline "You love ice cream!"
答案 1 :(得分:3)
我给出的记录是,我不完全确定它是哪种类型,我试图通过模式匹配来解决这个问题。
这是不可能的。类型仅在编译时存在,因此无法在运行时检查它的类型。
换句话说,在一个有效的程序中,你可以在每个表达式上放置一个类型注释(在大多数情况下,由于类型推断,你不必这样做)。如果你不能这样做那么你应该以不同的方式设计你的程序,比如使用其他人建议的和类型 - 在这种情况下,两个值将具有相同的类型(在编译时)但是具有不同的构造函数(在运行时)。 / p>
答案 2 :(得分:1)
您尝试在不使用变体类型的情况下匹配不同类型。
您正在使用的模块语法无济于事,因为模块只是构造代码。您可以定义以下类型:
type a = {
temperature: float;
toppings: string list;
}
type b = {
flavour: string;
colour: string;
volume: int;
}
但结果会是一样的。
消除歧义的方法是使用变体类型(或以下示例中未描述的联合类型):
let printFavoriteTreat treat = match treat with
| `A{ Candy.
flavour = "mint";
colour;
volume } -> "It's Candy"
| `B { IceCream.
temperature;
toppings } -> "It's IceCream"
;;
并且
let () = printFavoriteTreat (`A example)