возвращая значение списка с той же строкой [SML] - PullRequest
0 голосов
/ 15 мая 2018

Я написал следующую функцию в SML:

fun find_value [] item = ~1.0
  | find_value ((x:string,y:real)::xt) item = 
    if item = x then y
    else find_value xt item;

Эта функция получает список string * real и string и возвращает значение элемента с тем же string.Например:

- find_value [("goo",4.0),("boo",5.0)] "goo";
val it = 4.0 : real`. 

Проблема в моей реализации, она вернет ~1.0, если не найдет элемент со строкой x.поэтому, если, например, у меня есть элемент со значением ~1.0, он вернет его, и я не буду знать, является ли список пустым, или нет элемента в списке, или был элемент с такой же строкой и значением~1.0.

Пример:

find_value [("goo",~1.0),("boo",5.0)] "goo";
find_value [] "goo";

оба вернут val it = ~1.0.Есть ли другая идея для реализации?

1 Ответ

0 голосов
/ 15 мая 2018

Какой отличный вопрос. Для этого предназначен тип 'опция ( документация , Q & A ).

Ваш find_value может выглядеть следующим образом:

fun find_value [] _ = NONE
  | find_value ((key,value)::pairs) key1 =
      if key = key1
      then SOME value
      else find_value pairs key1

Теперь ваши два примера будут:

- find_value [("goo",~1.0),("boo",5.0)] "goo";
val it = SOME ~1 : real option
- find_value [] "goo";
val it = NONE : 'a option

Теперь абоненты find_value должны проверить, существует ли значение, например, с:

case find_value "foo" of
     NONE       => ... do some error handling ...
   | SOME value => ... proceed ...

Менее безопасная альтернатива - исключения:

exception NotFound of string
fun find_value [] key1 = raise NotFound key1
  | find_value ((key,value)::pairs) key1 =
      if key = key1
      then value
      else find_value pairs key1

Преимущество здесь в том, что вам не нужно распаковывать результат, в зависимости от того, найден он или нет, и если вы не знаете, как правильно обработать, что значение не найдено, вы можете просто отложить от перехвата исключения до нужной точки в стеке вызовов.

Но недостатком является то, что вы должны помнить, что нужно перехватить исключение, и что вы не можете быть уверены, что код, вызывающий другой код, будет свободен от исключений, поскольку любая функция, которая вызывает исключение, будет "портить" своих вызывающих.

Как правило, избегать исключений в коде, когда вы учитесь использовать строго типизированный язык программирования, потому что тогда компилятор и вы сможете лучше рассуждать о возможных сценариях при запуске программы.

...