Конструктор данных не находится в области видимости - PullRequest
0 голосов
/ 19 января 2019

Я изучаю Haskell и пишу простую программу.Теперь у меня проблема, которая для меня довольно запутанная.Вот код:

data VariableName = X|Y deriving Show  
getValue :: VariableName -> Int
getValue X = 5
getValue Y = 13

data Expression = Constant|Variable|Add|Multiply deriving Show
evaluate :: Expression -> Int
evaluate Constant x = x
evaluate Variable x = getValue x
evaluate Add x y = x+y
evaluate Multiply x y = x * y

Я ожидаю вывод:

Constant  20  = 20

, но я получаю

*Main> evaluate Constant 20

<interactive>:79:1: error:
    Variable not in scope: evaluate :: t0 -> Integer -> t

<interactive>:79:10: error: Data constructor not in scope: Constant

Но когда, например: я пишу

*Main> getValue X
5

Какой правильный ответ.Я только что начал Haskell, что весьма сбивает меня с толку.Некоторая помощь будет высоко ценится.

1 Ответ

0 голосов
/ 21 января 2019

Давайте посмотрим на ошибки:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...