user1233156
user1233156

Reputation: 25

Data constructor not in scope

I'm learning Haskell and writing a simple program. Now I'm getting a problem, which for me, is quite confusing. Here is the code:

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

I expect the output:

Constant  20  = 20

but I'm getting

*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

But when e.g.: I write

*Main> getValue X
5

Which is the right answer. I just started Haskell, which is way this is quite confusing for me. Some help would be much appreciated.

Upvotes: 0

Views: 4258

Answers (1)

DarthFennec
DarthFennec

Reputation: 2778

Let's take a look at the errors:

Variable not in scope: evaluate :: t0 -> Integer -> t

Data constructor not in scope: Constant

These mean that you haven't defined the evaluate function and the Constant constructor (even though you clearly have). But you say when you use getValue and X, those work?

This doesn't appear to be the (extremely common) multiline ghci confusion, as suggested in a comment. First, the error you get from that tends to be a non-exhaustive patterns, which is not what you're getting. Second, your ghci prompt reads *Main> instead of Prelude>, which implies that you've :loaded a file. Said file simply hasn't defined the code you expect it to have.

My guess is that is you wrote the first part of the code in the file, then :loaded it properly, then modified the file and forgot to :reload, so the changes you made were never loaded.

Another possibility is that you put a module Main (VariableName (..), getValue) where at the beginning of your file, and forgot to add your new exports to it. But that seems less likely.

If none of the above works, just try closing ghci, opening it again, and :loading the file anew.


Even once you fix that issue, there are a number of other errors you'll run into, mostly to do with parentheses. In Haskell, When you write something like this:

evaluate Constant 20

It means "call the evaluate function, and pass it two arguments: Constant and 20". This implies evaluate :: Expression -> Int -> Int, but you really want evaluate :: Expression -> Int. So you need parentheses:

evaluate (Constant 20)

This means "call the Constant constructor with one argument 20, and pass that value as the single argument to evaluate".


Not only must you make this change at the call site, you also need it in the definition. Currently, you have:

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

Each of these patterns expects a different number of arguments: the first two expect two arguments, and the last two expect three arguments. The problem is that x and y are being seen as arguments to the function, not the constructors. To change this, you need parentheses:

evaluate :: Expression -> Int
evaluate (Constant x) = x
evaluate (Variable x) = getValue x
evaluate (Add x y) = x+y
evaluate (Multiply x y) = x * y

The final change you need to make is in the constructor definition: you need to tell the constructors that they take arguments in the first place. Currently your data definition looks like this (I've added formatting):

data Expression = Constant
                | Variable
                | Add
                | Multiply
                deriving Show

None of these constructors currently take arguments: they're values (like True, X, Nothing, etc), rather than value constructors. This is not what you want. You need to give the types of the arguments for each constructor, like so:

data Expression = Constant Int
                | Variable VariableName
                | Add      Int Int
                | Multiply Int Int
                deriving Show

Upvotes: 1

Related Questions