Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Not in scope: data constructor in Haskell

Tags:

haskell

Please tell me what is the problem?

data Stack' v = Stack' [v] Int deriving (Show)
...
type StackInt = Stack' Int 

main = print(StackInt [1,2,3] 4)

The error i am getting is

Not in scope: data constructor `Stackint'

What is wrong?

like image 543
Manoj R Avatar asked Sep 06 '12 14:09

Manoj R


People also ask

What does variable not in scope mean in Haskell?

(When GHC complains that a variable or function is "not in scope," it simply means that it has not yet seen a definition of it yet. As was mentioned before, GHC requires that variables and functions be defined before they are used.)

What is data constructor in Haskell?

Data constructors are first class values in Haskell and actually have a type. For instance, the type of the Left constructor of the Either data type is: Left :: a -> Either a b. As first class values, they may be passed to functions, held in a list, be data elements of other algebraic data types and so forth.

Is maybe a data constructor in Haskell?

Maybe is a type constructor because it is used to construct new types (the result type depends on the type of a in Maybe a ), where such a type might be Maybe Int (notice, there's no type param a anymore, i.e. all type parameters are bound).

Is Io a data constructor in Haskell?

IO is a type constructor, not a value constructor. IO True would be a type, not a value (if True was a type).


2 Answers

It looks to me like you are confusing the concepts of types and constructors, this is a common problem as they live in separate namespaces and are often given the same name. In the Haskell expression

data SomeType = SomeType Int

say, you are actually defining the type SomeType and a constructor SomeType. The type is not a function in the normal sense, but the constructor is. If you asked ghci for the type of SomeType you would get this:

:t SomeType
SomeType :: Int -> SomeType

Now, a type declaration is just a shorthand for a longer type definition, in your case making StackInt a synonym of Stack' Int. But in order to construct a value of this type you still need to use the constructor Stack' (which has type [v] -> Int -> Stack' v). So your code should be

data Stack' v = Stack' [v] Int deriving (Show)

main = print(Stack' [1,2,3] 4)

If you wanted to be sure that the type was Stack' Int then you could add a function

data Stack' v = Stack' [v] Int deriving (Show)

stackInt :: [Int] -> Int -> Stack' Int
stackInt list i = Stack' list i

main = print(stackInt [1,2,3] 4)

EDIT: Not also that I've written stackInt list i = Stack' list i for transparency here, but you can write it more elegantly just as stackInt = Stack'. It is the type constraint that makes sure that you get the right type here.

You could also have both the new function and the type synonym if you wanted, ie

data Stack' v = Stack' [v] Int deriving (Show)
type StackInt = Stack' Int

stackInt :: [Int] -> Int -> StackInt
stackInt list i = Stack' list i

main = print(stackInt [1,2,3] 4)
like image 131
Vic Smith Avatar answered Sep 19 '22 02:09

Vic Smith


The name of the constructor is Stack', not StackInt. Creating a type alias using type does not create an alias for the constructors (which wouldn't make sense since there may be many constructors for the type and their names don't have to be related the type name at all).

like image 26
sepp2k Avatar answered Sep 20 '22 02:09

sepp2k