首页 > 解决方案 > 使用 SML 中的选项,模式匹配

问题描述

我正在尝试从 SML 中的列表函数构建一个 get 元素:

fun get_nth e =
    case e of
    [] => NONE
    | (x::xs, n) => if n = 1
                  then SOME x
                  else SOME get_nth(xs, n-1)

这会产生以下错误:

hw1pm.sml:72.24-72.45 Error: operator is not a function [tycon mismatch]
  operator: ('Z -> 'Y) option
  in expression:
    (SOME get_nth) (xs,n - 1)
hw1pm.sml:68.5-72.45 Error: types of rules do not agree [tycon mismatch]
  earlier rule(s): 'Z list -> 'Y option
  this rule: _ list * [- ty] -> _ option
  in rule:
    (:: (x,xs),n) =>
      if n = 1 then SOME x else (SOME get_nth) (xs,<exp> - <exp>)

我认为我对选项的理解不够好,我做错了什么?

标签: smlnj

解决方案


get_nth已经产生了一个option,所以没有必要用SOME.
此外,函数应用程序绑定非常紧密 - 正如 SML 所说,您实际上拥有 ( 的等价物SOME get_nth) (xs, n-1),这意味着这SOME get_nth将是一个函数。
(如果添加SOME正确,它本来是SOME (get_nth(xs, n-1)).)

发生第二个错误是因为您的模式匹配也错误;在一种情况下,您不能有一个列表 ( []),而在另一种情况下则不能有一对。

通过这两个修复,您将获得

fun get_nth e =
    case e of
      ([], _) => NONE
    | (x::xs, n) => if n = 1
                  then SOME x
                  else get_nth(xs, n-1)

但定义一个具有多个模式子句的函数比使用更常见case

fun get_nth ([], _) = NONE
  | get_nth (x::xs, n) = if n = 1
                         then SOME x
                         else get_nth(xs, n-1)

推荐阅读