Junhan Liu
Junhan Liu

Reputation: 55

Haskell, How could I construct a new datatype so that the value of that type is 1 or 2 or 3?

I want to construct a new data type called Oct, and it should return 1 or 2 or 3, so my code is something like this : data Oct = 1|2|3

but the Haskell shows the error like this: Cannot parse data constructor in a data/newtype declaration: 1

And I don`t know what does this error means. how should I fix it?

Upvotes: 4

Views: 1218

Answers (3)

Sarfaraz Nawaz
Sarfaraz Nawaz

Reputation: 361352

I think you want to limit the value of Int to one of {1,2,3}. If so, you can define a newtype Oct as:

newtype Oct = Oct Int deriving(Show)

and then define a function oct that makes Oct as:

oct :: Int -> Oct
oct n 
   | n > 0 && n < 4 = Oct n 
   | otherwise      = error "invalid value: " ++ show n

If throwing error is not acceptable, then maybe Maybe will help:

oct :: Int -> Maybe Oct
oct n 
   | n > 0 && n < 4 = Just (Oct n) 
   | otherwise      = Nothing

Hope that helps.

Upvotes: 5

luqui
luqui

Reputation: 60463

You can't really make arbitrary subtypes like that. What you can do is make a data type with three constructors, you just have to understand some things about data declarations:

When you declare a new data type, you declare it with its constructors. The constructors you use are brand new names that don't already have a meaning. The datatype and its constructors must all begin with a capital letter. So you say

data Oct = One | Two | Three

This declares the type Oct and three values One, Two, and Three -- four declarations at once.

Another alternative is to use a smart constructor with a type like

newtype Oct = Oct Int

as shown in more detail in @Nawaz's answer.

There is a way to make numeric literals work, so you can use 1 :: Oct, but for this case it's not good because (the way the libraries are designed) numeric literals ought to come with numeric structure as well, which Oct doesn't have (well, unless you want to start doing fancy math). Also using 4 :: Oct would typecheck but would be a runtime error, which we also don't like.

Upvotes: 7

Code-Apprentice
Code-Apprentice

Reputation: 83527

but the Haskell shows the error like this: Cannot parse data constructor in a data/newtype declaration: 1

This error message tells you that 1 is not a valid name for a data constructor. The rules for names of data constructors are similar to those of variables in most languages. Here the compiler complains because the name starts with a digit, which is not allowed.

Upvotes: 1

Related Questions