簡體   English   中英

我將如何編寫通用 function 來處理 ReScript 中的多種記錄類型?

[英]How would I write a generic function to handle multiple record types in ReScript?

給定以下人為的示例,是否可以編寫一個get function 可以處理具有a屬性的任何記錄?

type type_one = {a: int}
type type_two = {a: int, b: int}

let example_one = {a: 1}
let example_two = {a: 1, b: 2}

let get = record => record.a

Js.log(get(example_one)) // notice the error here
Js.log(get(example_two))

重新編寫游樂場

如果沒有,object 是否可以做到這一點? 或者,處理這種情況的最佳方法是什么?

它不是。 因為記錄是名義上(而不是結構上)類型的,所以無法指定“任何帶有a字段的記錄”。 因此get將被推斷為具有編譯器看到的帶有a字段的最后一個類型,即type_two

但是有 object 類型,它是帶有子類型的結構,允許這樣做:

type type_one = {"a": int}
type type_two = {"a": int, "b": int}

let example_one = {"a": 1}
let example_two = {"a": 1, "b": 2}

let get = (record) => record["a"]


Js.log(get(example_one)) // notice no error here
Js.log(get(example_two))

但請注意,使用對象而不是記錄需要權衡取舍,例如不能以模式解構它們。

另外,作為旁注,在某些語言中可以實現的另一種方法是通過臨時多態性,通過顯式定義一個公共接口和附加到特定類型的實現(在 Haskell 中稱為類型類,在 Rust 中稱為特征)。 遺憾的是,Rescript 和 OCaml 目前也不支持這一點,盡管有一個以模塊化隱式形式的 OCaml 提議。 但是,您仍然可以使用模塊定義通用接口和實現,並顯式傳遞它們:

type type_one = {a: int}
type type_two = {a: int, b: int}

let example_one = {a: 1}
let example_two = {a: 1, b: 2}

module type S = {
  type t
  let getA: t => int
}

module T1 = {
  type t = type_one
  let getA = (record: t) => record.a
}

module T2 = {
  type t = type_two
  let getA = (record: t) => record.a
}

let get = (type a, module(T: S with type t = a), record: a) => T.getA(record)

Js.log(get(module(T1), example_one)) // notice no error here
Js.log(get(module(T2), example_two))

這個用例可能有點冗長,但這有時會派上用場。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM