OCAML:具有多种类型的参数

OCAML: Parameter with multiple types

Ocaml 中是否可以有多种类型的参数?

我定义了两种不同的类型,这两种类型都有一个地址字段:

type symbol =
  {
    address : string;
    name : string;
  }


type extern_symbol =
  {
    address : string;
    name : string;
    ...
  }

我还有一个函数,它以 符号列表 作为参数,并检查 地址 字段。现在我想重用 extern_symbol 列表 的函数代码。该函数将与另一个列表完全相同。有没有一种无需编写重复代码即可完成此操作的方法?

您不能直接使用记录参数执行此操作,因为所有记录类型都是不同的。 “具有名为 address 类型字符串的字段的任何记录”的概念没有类型。因此你不能有那种类型的参数。

当然,您可以只将地址而不是整个记录传递给函数,如果这就是您所需要的。

或者您可以传递一个提取地址的函数:

let myfun address_of r =
    do_what_you_want (address_of r)

let internal_addr (r: symbol) = r.address
let external_addr (r: extern_symbol) = r.address

myfun internal_addr r1
myfun external_addr r2

那么 myfun 有这样的类型:

(a -> string) -> a -> result

这推广到可以应用于两种记录类型的其他操作。

您也可以使用对象类型而不是记录。 一种类型,表示“具有名为address的方法的任何对象,returns一个字符串”:

< address : string; .. >

例如:

# let myfun2 ob = do_what_i_wanted ob#address;;
val myfun2 : < address : string; .. > -> string = <fun>

最后,你可以让这两种类型成为同一类型的不同变体:

type symbol =
   | Internal of { address: string; name: string }
   | External of { address: string; name: string; ... }

那么用同一个函数处理它们就没有问题了:

let myfun3 sym =
    let addr =
        match sym with
        | Internal x -> x.address
        | External x -> x.address
    in
    do_what_i_wanted addr