Opa 在筛选sum类型的列表后访问记录

Opa 在筛选sum类型的列表后访问记录,opa,Opa,我有一份清单 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

我有一份清单

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
正如您所看到的,在找到之后,我肯定会得到
类型的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.

我怎么能对编译器说,我只提取了一种类型的sum类型,而且我有一种很好的类型来访问记录

嗯,您不能真正通知编译器列表中只存在子类型。。。但是,您只能显式创建具有此子类型的列表。实际上,您要查找的是
List.find\u map
,它找到与特定条件匹配的第一个元素并将其映射(您使用此映射从
my\u sum
投影到其大小写
type\u a
)。下面是一段完整的工作代码(自行编译):

如果stdlib中没有
List.find_map
函数,那么仍然有很多方法可以做到这一点。可能最简单的方法是使用
List.filter\u map
获取
列表(键入a)
,然后使用
List.head\u opt
获取其头部

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")