2016-11-11 5 views
0

У меня есть следующий фрагмент кода:Есть ли более эффективный способ обработки целочисленного типа данных?

datatype eInt = infinity of int | 0 | Int of int; 

exception undefined; 
fun eAdd(e1:eInt, 0:eInt) = e1 
    | eAdd(0, e2) = e2 
    | eAdd(e1, infinity) = infinity 
    | eAdd(infinity, e1) = infinity 
    | eAdd(infinity, ~infinity) = raise undefined 
    | eAdd(~infinity, infinity) = raise undefined 
    | eAdd(e1, e2) = e1 + e2; 

Там новый тип данных, который позволяет в течение трех типов: бесконечность, 0, и междунар. Я думаю, 0 может быть избыточным, но я не уверен.

Я использовал сопоставление образцов, чтобы сформулировать различные типы возможных результатов, добавив два eInts вместе.


Существует четыре разных результата.

  • Если есть 0, вернуть другой ИНТ
  • Если есть ∞, вернуть ∞
  • Если есть ∞ и -∞, вернуть неопределенную
  • Что-нибудь еще, возвратите добавление двух их

Единственное, что я могу думать, что делает этот алгоритм более эффективным, если бы я, чтобы удалить двойные случаи, и в конце концов, запустить алгоритм снова после обращения (e1, e2) в (e2, e1).

Любые идеи по повышению эффективности? Я буду добавлять другие операции, такие как деление, которые будут иметь еще больше случаев.

ответ

2
  1. Да, 0 является излишним, так как у вас также есть Int 0.

  2. Использовать имена конструкторов верхнего регистра.

  3. Вы действительно не сказали, что вы подразумеваете под Infinity of int. Судя по вашим примерам, вас интересует только то, является ли бесконечность положительной или отрицательной, поэтому int также является излишним.

  4. Вместо использования исключений используйте опцию .

Таким образом, вы можете иметь

datatype IntExt = PosInf 
       | NegInf 
       | Int of int 

fun extAdd (PosInf, i2) = if i2 = NegInf then NONE else SOME PosInf 
    | extAdd (i1, PosInf) = if i1 = NegInf then NONE else SOME PosInf 
    | extAdd (NegInf, _) = SOME NegInf 
    | extAdd (_, NegInf) = SOME NegInf 
    | extAdd (Int a, Int b) = SOME (Int (a+b)) 

Если вы хотите эффективной реализации, рассмотрим процесс кодирования целых чисел, как IEEE 754.

+0

Привет, Саймон, просто хотел сказать спасибо в целом. Ты помогаешь мне много, и я очень ценю то, что ты делаешь. Я, после публикации, пересмотрел свой ответ. Я внес большую часть изменений, кроме внесенных изменений. Я изменю свой вопрос, чтобы другие могли видеть, что у меня есть сейчас. Единственное различие заключается в том, могу ли я спросить, что 'NONE' и' SOME' делают в этом сценарии? –

+0

@AndrewRaleigh: Комментарии к StackOverflow не подходят для обсуждения вперед и назад. Я рекомендую вам прочитать соответствующий раздел вводной книги, такой как [H & R] (http://www.it.dtu.dk/introSML/). Или вы можете google вокруг: [здесь] (http://stackoverflow.com/questions/24980801/what-are-the-options-some-and-none-sml), [здесь] (http: //courses.cs .washington.edu/courses/cse341/04wi/lectures/10-ml-exceptions.html) (последний ресурс кажется довольно хорошим). –

+0

Спасибо за книгу, я искал хороший :) –

1
  • Я удалил тег «рекурсия», так как в этой функции нет рекурсии.
  • Если вы особенно обеспокоены эффективностью, закажите предложения от большинства до наименее частых. Вероятно, это означает, что ваши «неопределенные» предложения продолжатся.
  • Проверьте относительную эффективность выбора предложения. Возможно, что время, затраченное на оценку аргументов и переключение в половину времени, будет потреблять любую экономию от более короткого кода.
+0

Спасибо, я добавил шаблон соответствия шаблону, извините за неправильный тег.Не будет ли перемещение неопределенного значения «eAdd (e1, e2)» всегда будет оцениваться? Я попробую. Что касается третьего момента, это звучит правильно. Спасибо за ответ, я ценю это :) –

+0

Oh. Duh. Да, оставьте предложение по умолчанию для последнего. OOPS! :-) – Prune

Смежные вопросы