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.