简体   繁体   中英

Create a type that is a subset of an other type

How can you create a type that is a subset of an other type? I want a string type that only contains alphanumeric characters.

So I want something like this

type AlphNumString = [AlphaNumChar]
data AlphaNumChar = ???? filter (isAlphaNum) Char ????

The standard way to do this is with so-called " smart constructors ".

First, you define a new type that's identical to the old one:

newtype AlphNumString = X String

Next, you write the smart constructor itself:

toAlphNumString :: String -> AlphNumString
toAlphNumString txt = X (filter isAlphNum txt)

Finally, you make it so toAlphNumString is the only way to create an AlphNumString .

module Foo (AlphNumString (), toAlphNumString, ...) where ...

Note that this does not allow you to use an AlphNumString like a normal String ; you can't create "subtypes" like that in Haskell. So you'll also need another function

fromAlphNumString :: AlphNumString -> String
fromAlphNumString (X txt) = txt

This concept of types that are "subsets" of other types based on some predicate is called refinement types. For Haskell, this is implemented as LiquidHaskell .

However, I would consider this an ongoing research. In practice, I would go with a newtype and dynamic checks, as MathematicalOrchid describes in their answer.

In a dependently typed language (which Haskell is not, yet) you could use dependent pairs for this.

data Sigma : (t : Type) -> (t -> Type) -> Type where
  MkSigma : (x : t) -> p x -> Sigma t p

data IsAlphaNum : (c : Char) -> Type where
  MkIsAlphaNum : isAlphaNum c = True -> IsAlphaNum c

Then Sigma Char IsAlphNum would be a type representing alphanumeric characters. Each element of that type would consist of a character and a proof that the character is alphanumeric.

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