iluvAS
iluvAS

Reputation: 513

Defining a new haskell type

I'm new to haskell. I've two questions but they're somewhat related.

Is it possible to define a type of Integers excluding specific integers for example zero. Or just positive numbers.

data allIntsButZero = ..? { a /= 0 | for all a in Int} ??
data positiveInts   = ..? { a >= 0 | for all a in Int} ??

In short, can I define a type as a subset of another type?

Secondly, can i define a type where there is a logic imposed? e.g.

type doublePair = (Int, Int * 2) {- where snd is always 2 times of fst -}
data validDDMMYYYY = G Int Int Int {- where complies to gregorian calendar -}

Upvotes: 0

Views: 105

Answers (1)

leftaroundabout
leftaroundabout

Reputation: 120711

The type doublePair of these really doesn't make sense. If the snd is always twice the fst, then it doesn't actually contain any information! So, this type is definitely better expressed as

newtype DoubleableInt = DoubleableInt {getDoubleableInt :: Int}

The others do make some sense, but I think you're still a bit missing the point of an abstraction. The type validDDMMYYYY is probably supposed to express a date, i.e. a point in time. How it respresents this shouldn't really be the user's concern: if a library depends on a certain representation, it should simply should offer specialised “smart constructors” to ensure well-formedness. Like

newtype AllIntsButZero = AllIntsButZero {getNonzeroInt :: Int}

mkNonzeroInt :: Int -> Maybe AllIntsButZero
mkNonzeroInt 0 = Nothing
mkNonzeroInt n = AllIntsButZero n

You may then refuse to export the AllIntsButZero constructor (which would allow users to form incorrect AllIntsButZero 0):

module RestrictedNumbers (AllIntsButZero, getNonzeroInt, mkNonzeroInt) where

This way, users will only see AllIntsButZero as a “black box”, and the functions they can use with it are guaranteed to yield well-formed values.

Upvotes: 3

Related Questions