我有一个
列表type my_sum = {a : type_a} / {b : type_b}
mylist = [{field_only_in_a = "test"} : type_a,{haha=3 ; fsd=4} : type_b]
我想这样做:
result = List.find( a -> match a with
| {a = _} -> true
| _ -> false
end,
mylist)
if Option.is_some(result) then
Option.some(Option.get(result).field_only_in_a)
else
Option.none
就像你可以看到的那样,在找到之后我肯定会得到一些type_a
,但是在编译时我得到了:
Record has type
{ a : type_a } / { b : type_b } but field access expected it to have type
{ field_only_in_a: 'a; 'r.a }
Hint:
You tried to access a sum type with several cases as a record.
我怎么能对编译器说,我只提取了一种类型的和类型,并且我有良好的类型来访问记录......?
答案 0 :(得分:4)
嗯,您无法真正通知编译器列表中只存在一个子类型...但您可以显式创建仅包含此子类型的列表。实际上,您正在寻找的是List.find_map
,它找到符合特定条件的第一个元素并对其进行映射(您使用此映射从my_sum
投影到其案例type_a
)。下面是一个完全正常工作的代码(自行编译):
type type_a = {fld_a : string}
type type_b = {fld_b : int}
type my_sum = {a : type_a} / {b : type_b}
mylist = [{a = {fld_a = "test"}}, {b = {fld_b = 10}}] : list(my_sum)
get_first_a(l : list(my_sum)) : option(type_a) =
List.find_map(
(el -> match el
| ~{a} -> some(a)
| _ -> none
), l)
_ = prerr("First a-typed element of {mylist} is {get_first_a(mylist)}\n")
如果stdlib中没有List.find_map
函数,那么仍然有很多方法可以做到。可能最简单的方法是使用List.filter_map
来获取list(type_a)
,然后使用List.head_opt
来获得它。