函数从位置转换为元素

时间:2012-02-20 02:41:05

标签: ocaml

我有这个列表组合:list + undefined list 我写这个函数从那里返回元素。

let name_of_num list undefined_list len_undefined k =
  if k < len_undefined then List.nth undefined_list k else
    List.nth list (k - len_undefined)

val name_of_num : 'a list -> 'a list -> int -> int -> 'a

但我的问题是,当我申请我的函数时,列表与未定义的列表有不同的类型。所以这个函数不能通过编译器。其中undefined是一个字符串列表。

let len_undefined xsds = List.length (undefined xsds)

let xsds_of_int xsds =
List.map (List.map (name_of_num xsds undefined (len_undefined xsds)))

xsds在我的计划中有xsds类型。如果我将undefined替换为xsds,就像这个函数一样:

let xsds_of_int xsds =
List.map (List.map (name_of_num xsds xsds (len_undefined xsds)))

它有效。如何在k < len_undefined

时写下第二个条件
let name_of_num list len_undefined k =
  if k < len_undefined then ??? else
    List.nth list (k - len_undefined)

谢谢。

1 个答案:

答案 0 :(得分:3)

你要求的似乎是不可能的。您想提供两个不同类型的列表。但是你的函数有时会返回list的元素,有时会返回undefined_list的元素。由于OCaml是强类型语言,因此函数必须始终返回相同类型的值。因此listundefined_list必须具有相同的类型。

如果不了解您的要求,很难知道建议什么。但是,定义一个结合了您喜欢的任何两种类型的 new 类型非常容易。 (或任何有限数量的类型。)

type either = A of typea | B of typeb

值(A x)表示值typea,值(B y)表示值typeb。但是这两个值是相同的类型,类型为either

然后,您可以定义name_of_num以获取两个不同类型的列表,但它将返回类型either。如果您希望获得更高级的功能,可以将either定义为参数化类型,这将允许name_of_num具有多态性。这是否是一件好事,取决于你想要解决的问题。

我不确定这会解决您的问题,但我希望它有所帮助。

修改

如果您使用either类型,以下是您的函数的外观。生病 将int用于一种类型,将string用于另一种类型。

type either = A of int | B of string

let name_of_num list undefined_list len_undefined k =
  if k < len_undefined then
    (B (List.nth undefined_list k))
  else
    (A (List.nth list (k - len_undefined)))

val name_of_num : int list -> string list -> int -> int -> either = <fun>
# 

修改2

让我觉得您可能想要使用异常来解决您的问题。如果您正在尝试填充映射值矩阵,并且如果超出范围的输入很少(并指示错误),则只能在看到错误输入时引发异常。呼叫者可以捕获异常并决定该怎么做。然后,您的name_of_num函数将始终返回xsd。 (如果它看到一个坏的值,它根本不会返回。)