简体   繁体   中英

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? eg

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

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 , ie 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM