如何将OCaml列表分为头尾?

时间:2015-10-23 02:06:10

标签: list functional-programming ocaml

我刚刚学习OCaml,现在,当我需要访问头部时,我使用match l with h::t ->来分割列表。但我确信是以这种方式拆分列表的更好方法。我似乎无法在网上找到太多东西。也许我没有以正确的方式寻找。

3 个答案:

答案 0 :(得分:6)

这是最好的方式。

List.hdList.tl函数来获取hdtl但标准库中没有可用于一次移动的头部和尾部的函数。另外List.hdList.tl是不安全的:如果给它们一个空列表,它们会引发运行时异常:

# List.hd [];;
Exception: Failure "hd".

如果您100%确定参数不能为空,则可以安全地使用它们,但实际上您的推测通常不正确。 List.hdtl可能是非常好的错误来源。

使用带有letlet (h::t) = l in ...的模式是可能的,但它也存在运行时失败的风险,但编译器可以告诉您,您的模式并非详尽无遗且缺乏对{{1 }}

[]可以包含多个案例,您可以涵盖match[]的案例。如果您忘记match l with [] -> ... | (h::t) -> ...的情况,编译器可以向您发出警告。

答案 1 :(得分:0)

我不了解OCaml,但Haskell提供了这些,你可以轻松翻译:

-- I think ML might write this signature
-- uncons : 'a list -> ('a * 'a list) option
uncons :: [a] -> Maybe (a, [a])
uncons (x : xs) = Just (x, xs)
uncons [] = Nothing

maybe :: b -> (a -> b) -> Maybe a -> b
maybe def f Nothing = def
maybe def f (Just x) = f x

然后你可以写像

这样的东西
drop1 :: [a] -> [a]
drop1 = maybe [] snd . uncons

答案 2 :(得分:0)

此问题的OCaml方式是表达式

match l with
| [] -> some_expr
| x :: xs -> some_other_expr
  • 最糟糕的解决方案是使用List.hdList.hd,导致可能的运行时异常。

  • 第二个更糟糕的解决方案是不完整的匹配,例如match l with x :: xs也导致相同的运行时错误,但您至少得到编译时警告,并且您错过了匹配的案例。< / p>

请注意,如果不使用,您可以忽略匹配的某些部分, 所以你的代码是自我记录的:

let hd_option lst =
match lst with
| [] -> None
| x :: _ -> Some x (* the tail is not used, so I just don't name it *)