Работа с опциями в SML, сопоставление с образцом - PullRequest
0 голосов
/ 29 февраля 2020

Я пытаюсь построить элемент get из списка в SML:

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>)

Не думаю, что я хорошо понимаю опции достаточно, что я делаю не так?

1 Ответ

0 голосов
/ 03 марта 2020

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)
...