如何将 OCaml 列表拆分为头部和尾部?
How do I split an OCaml list into head and tail?
我正在学习 OCaml,现在,当我需要访问头部时,我使用 match l with h::t ->
来拆分列表。但我敢肯定 has 是以这种方式拆分列表的更好方法。我似乎无法在网上找到很多。可能我没看对方向
这是最好的方法。
有函数List.hd
和List.tl
可以得到hd
和tl
但是标准库中没有函数可以得到头尾合二为一移动。此外 List.hd
和 List.tl
是不安全的:如果你给它们一个空列表,它们会引发运行时异常:
# List.hd [];;
Exception: Failure "hd".
如果您 100% 确定参数不能为空,则可以安全地使用它们,但您的推测在实践中往往不正确。 List.hd
和 tl
可能是非常好的错误来源。
使用 let
的模式:let (h::t) = l in ...
是可能的,但它也有运行时失败的风险,但编译器会告诉你你的模式并不详尽并且缺乏 let (h::t) = l in ...
的处理=21=].
match
可以有多个案例,您可以覆盖 []
的案例:match l with [] -> ... | (h::t) -> ...
。如果您忘记 []
的大小写,编译器会警告您。
我不懂 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
这个问题的 OCaml 方法是表达式
match l with
| [] -> some_expr
| x :: xs -> some_other_expr
最糟糕的解决方案是使用 List.hd
或 List.hd
,可能导致运行时异常。
第二个更糟糕的解决方案是不完全匹配,例如 match l with x :: xs
也会导致相同的运行时错误,但您至少会收到编译时警告,以及匹配的情况你错过了。
注意,部分不使用的匹配可以忽略,
所以你的代码是自我记录的:
let hd_option lst =
match lst with
| [] -> None
| x :: _ -> Some x (* the tail is not used, so I just don't name it *)
我正在学习 OCaml,现在,当我需要访问头部时,我使用 match l with h::t ->
来拆分列表。但我敢肯定 has 是以这种方式拆分列表的更好方法。我似乎无法在网上找到很多。可能我没看对方向
这是最好的方法。
有函数List.hd
和List.tl
可以得到hd
和tl
但是标准库中没有函数可以得到头尾合二为一移动。此外 List.hd
和 List.tl
是不安全的:如果你给它们一个空列表,它们会引发运行时异常:
# List.hd [];;
Exception: Failure "hd".
如果您 100% 确定参数不能为空,则可以安全地使用它们,但您的推测在实践中往往不正确。 List.hd
和 tl
可能是非常好的错误来源。
使用 let
的模式:let (h::t) = l in ...
是可能的,但它也有运行时失败的风险,但编译器会告诉你你的模式并不详尽并且缺乏 let (h::t) = l in ...
的处理=21=].
match
可以有多个案例,您可以覆盖 []
的案例:match l with [] -> ... | (h::t) -> ...
。如果您忘记 []
的大小写,编译器会警告您。
我不懂 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
这个问题的 OCaml 方法是表达式
match l with
| [] -> some_expr
| x :: xs -> some_other_expr
最糟糕的解决方案是使用
List.hd
或List.hd
,可能导致运行时异常。第二个更糟糕的解决方案是不完全匹配,例如
match l with x :: xs
也会导致相同的运行时错误,但您至少会收到编译时警告,以及匹配的情况你错过了。
注意,部分不使用的匹配可以忽略, 所以你的代码是自我记录的:
let hd_option lst =
match lst with
| [] -> None
| x :: _ -> Some x (* the tail is not used, so I just don't name it *)