Can a Haskell data declaration be limited to type values

In Haskell, is there a way to limit a data type to the value of its components? I made an example. Let's say you have a game with checkers. The controller has a black or white type.

data CheckerType = BlackChecker | WhiteChecker deriving (Eq) data Checker = Checker CheckerType Int 

The game board for the check-game contains a set of black drafts and white drafts.

 data GameBoard = GameBoard ([Checker]) ([Checker]) 

In the previous declaration, is there a way to force Checkers in the first [Checker] to be black CheckerType, and the second to the opposite type?

+8
types declaration functional-programming haskell
source share
1 answer

The easiest way to do something like this is to parameterize the Checker type with the so-called phantom type:

 data Black data White 

Note that none of them have any meaning. They exist only to indicate the color of the Checker .

 data Checker a = Checker Int data GameBoard = GameBoard [Checker Black] [Checker White] 

By the way, you don't need those brackets in the GameBoard ad.

The disadvantage of this approach is that the two colors are now different, which means that you cannot write a function that accepts, say, a list of checkers of several colors, only one color.

You can make phantom types a little more specific to keep track of valid colors:

 data Black = Black data White = White data Checker a = Checker a Int type AnyChecker = Checker (Either Black White) 

But this can quickly become a lot of hassle to use.

What I suspect you really want is a way to limit the range of values ​​allowed in one context without making it a completely different type in all contexts. Unfortunately, in Haskell this is not entirely possible.

This is a reasonable idea, and some languages ​​have similar features. Thus, supporting such differences in a generalized way is not easy to add to an existing Haskell-type system without collateral damage, although, for example, making type inference less reliable even in code that does not use such a function.

+13
source share

All Articles