2012-06-15 3 views
0

Я недавно писал интерпретатор для базового языка программирования, и все прошло нормально. Однако кто-то может посоветовать мне лучший подход для добавления поддержки для парных. В настоящее время поддерживаются только Ints, но я хотел бы также добавить поддержку для Doubles.Haskell Выполняет арифметические операции над Ints и Double

ответ

4

типа ко а = [[вар, а]]

Это семейство типов. Env Int - это окружение int, Env Double - это двойная среда и так далее. Это не тот тип, который может содержать как ints, так и doubles, что, вероятно, вам нужно.

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

data Val = IntNum Int | DoubleNum Double 

, а затем вы можете иметь свою среду как

type Env = [ (Var, Val) ] 

(я не знаю, почему вы используете список списков здесь).

Необходимо определить арифметические операции отдельно для случаев IntNum и DoubleNum (и, возможно, для смешанных операндов, если ваш язык поддерживает это).

Добавление булевых элементов и списков является простым, просто добавьте еще несколько случаев к Val.

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

+0

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

+0

Почти внесенные изменения, однако я получаю ошибку компилятора в этой функции: 'initialiseVars :: [Decl] -> [(Var, Val)] -> [(Var, Val)] initialiseVars (d: ds) list = initialiseVars ds ((d, 0): list) initialiseVars [] list = list' Ошибка: «Нет экземпляра для (Num Val), возникающего из литерала« 0 », Возможное исправление: добавьте объявление экземпляра для (Num Val) "могут быть изменены только 5 минут (нажмите на это поле, чтобы уволить) – user1424720

+1

Почему вы пытаетесь инициализировать свои переменные до 0? 0 как-то особенное? Если вы хотите сделать это в любом случае, вам нужно выбрать, какой 0 вы хотите, целое число 0 или двойное 0. Следовательно, используйте 'IntNum 0' или' DoubleNum 0' вместо простого '0'. Еще лучше добавьте еще один случай в 'Val', скажем' data Val = ...| UndefinedVal' и инициализируйте это, и сообщайте об ошибке всякий раз, когда в выражении используется «UndefinedVal». –

2

Простым ответом будет определение типа варианта, который может содержать эфир Int s или Double s, например.

data Value = Int Int 
      | Double Double 

и изменить определение Env и других типов соответственно:

type Env = [[(Var, Value)]] 

data ValExpr = IVar Var 
      | IVal Value 
      ... 

Но если вы планируете добавить больше типов, я бы рассмотреть возможность использования GADT с.

РЕДАКТИРОВАТЬ: опечатка

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