在OCaml中列出转换错误

时间:2014-03-30 00:20:26

标签: ocaml

我是OCaml的新手,我正在尝试编写一个函数来执行此操作:

(4,a)(1,b)(2,c)(2,a)(1,d)(4,e) --> ((4 a) b (2 c) (2 a) d (4 e))

这就是我写的:

let rec transform l =
 match l with
 | (x,y)::t -> if x = 1 then y::transform(t) else [x; y]::transform(t)
 | [] -> []

我把它放在ocaml解释器中但是生成的错误如下:

Error: This expression has type int list
   but an expression was expected of type int

有人能帮忙吗?

2 个答案:

答案 0 :(得分:2)

您的示例转换并未明确该值的类型应该是什么。

如果它们应该是列表,则结果不是OCaml中的可能列表。 OCaml列表是同类的,即列表的所有元素具有相同的类型。这(实质上)是编译器抱怨的内容。

<强>更新

查看代码,问题在于:

if x = 1
then y :: transform (t)
else [x; y] :: transform t

让我们说y的类型是'athen之后的表达式似乎具有类型'a list,因为y是列表的头部。 else之后的表达式似乎具有类型'a list list,因为包含y的列表是列表的头部。它们的类型不同。

答案 1 :(得分:2)

主要问题是决定如何将某些内容表示为(4 a)b。通常的OCaml表示某种东西或其他东西的方式是变体,所以让我们定义其中一种:

type 'a element =
  | Single of 'a
  | Count of int * 'a

let rec transform = function
  | [] -> []
  | (x,y)::t ->
      if x = 1 then Single y::transform t
      else Count (x, y)::transform t

请注意,除非您使用顶层注册打印机,否则不会以您想要的方式打印。

或更好:

let compact (x, y) =
  if x = 1 then Single y else Count (x, y)

let transform list = List.map compact list