Давайте посмотрим на ошибки:
Variable not in scope: evaluate :: t0 -> Integer -> t
Data constructor not in scope: Constant
Это означает, что вы не определили функцию evaluate
и конструктор Constant
(даже если вы явноиметь).Но вы говорите, что когда вы используете getValue
и X
, это работает?
Это не является (чрезвычайно распространенной) многострочной ghci
путаницей, как предлагается в комментарии.Во-первых, ошибка, которую вы получаете от этого, как правило, non-exhaustive patterns
, а это не то, что вы получаете.Во-вторых, ваша подсказка ghci
читает *Main>
вместо Prelude>
, что означает, что вы :load
редактировали файл.Указанный файл просто не определил код, который вы ожидаете получить.
Я предполагаю, что вы написали первую часть кода в файле, затем :load
правильно его отредактировали, затем изменили файли забыл :reload
, поэтому сделанные вами изменения не были загружены.
Другая возможность заключается в том, что вы положили module Main (VariableName (..), getValue) where
в начало вашего файла и забыли добавить в него новый экспорт.Но это кажется менее вероятным.
Если ничего из вышеперечисленного не работает, попробуйте закрыть ghci
, открыть его снова и :load
заново файл.
Даже один разЕсли вы исправите эту проблему, вы столкнетесь с рядом других ошибок, в основном связанных с круглыми скобками.В Haskell, когда вы пишете что-то вроде этого:
evaluate Constant 20
Это означает «вызов функции evaluate
и передача ей двух аргументов: Constant
и 20
».Это подразумевает evaluate :: Expression -> Int -> Int
, но вы действительно хотите evaluate :: Expression -> Int
.Поэтому вам нужны круглые скобки:
evaluate (Constant 20)
Это означает, что «вызовите конструктор Constant
с одним аргументом 20
и передайте это значение в качестве единственного аргумента evaluate
».
Вы должны не только внести это изменение на сайте вызова, но и в определении.В настоящее время у вас есть:
evaluate :: Expression -> Int
evaluate Constant x = x
evaluate Variable x = getValue x
evaluate Add x y = x+y
evaluate Multiply x y = x * y
Каждый из этих шаблонов ожидает различное количество аргументов: первые два ожидают два аргумента, а последние два ожидают три аргумента.Проблема в том, что x
и y
рассматриваются как аргументы функции, а не конструкторы.Чтобы изменить это, вам нужны круглые скобки:
evaluate :: Expression -> Int
evaluate (Constant x) = x
evaluate (Variable x) = getValue x
evaluate (Add x y) = x+y
evaluate (Multiply x y) = x * y
Последнее изменение, которое вам нужно сделать, - это определение конструктора: вы должны сначала сказать конструкторам, что они принимают аргументы.В настоящее время ваше определение данных выглядит следующим образом (я добавил форматирование):
data Expression = Constant
| Variable
| Add
| Multiply
deriving Show
Ни один из этих конструкторов в настоящее время не принимает аргументы: это значения (например, True
, X
, Nothing
,и т. д.), а не конструкторы значений.Это не то, что вы хотите.Вам нужно указать типы аргументов для каждого конструктора, например:
data Expression = Constant Int
| Variable VariableName
| Add Int Int
| Multiply Int Int
deriving Show