Haskell 中的约束值类型
Constrained Value Types in Haskell
是否可以在 Haskell 中定义约束类型,即我希望能够表达,
Prelude> let legalCharacters = ' ':['A'..'Z']
Prelude> legalCharacters
" ABCDEFGHIJKLMNOPQRSTUVWXYZ"
作为一种类型,如果可能的话。
可以在现代 GHC 中完成(>= 7.10,也许已经是 7.8)。
{-# LANGUAGE KindSignatures, DataKinds, MonoLocalBinds #-}
import GHC.TypeLits
newtype LegalChar (legalSet :: Symbol)
= LegalChar {getLegalChar :: Char}
deriving (Show)
fromChar :: KnownSymbol legal => Char -> Maybe (LegalChar legal)
fromChar c
| c`elem`symbolVal r = Just r
| otherwise = Nothing
where r = LegalChar c
然后
*Main> fromChar 'a' :: Maybe (LegalChar "abc")
Just (LegalChar {getLegalChar = 'a'})
*Main> fromChar 'x' :: Maybe (LegalChar "abc")
Nothing
我认为在 GHC-8 中你甚至可以给 legalSet
那种 String
并取消 KnownSymbol
约束,不知道它是如何工作的。
是否可以在 Haskell 中定义约束类型,即我希望能够表达,
Prelude> let legalCharacters = ' ':['A'..'Z']
Prelude> legalCharacters
" ABCDEFGHIJKLMNOPQRSTUVWXYZ"
作为一种类型,如果可能的话。
可以在现代 GHC 中完成(>= 7.10,也许已经是 7.8)。
{-# LANGUAGE KindSignatures, DataKinds, MonoLocalBinds #-}
import GHC.TypeLits
newtype LegalChar (legalSet :: Symbol)
= LegalChar {getLegalChar :: Char}
deriving (Show)
fromChar :: KnownSymbol legal => Char -> Maybe (LegalChar legal)
fromChar c
| c`elem`symbolVal r = Just r
| otherwise = Nothing
where r = LegalChar c
然后
*Main> fromChar 'a' :: Maybe (LegalChar "abc")
Just (LegalChar {getLegalChar = 'a'})
*Main> fromChar 'x' :: Maybe (LegalChar "abc")
Nothing
我认为在 GHC-8 中你甚至可以给 legalSet
那种 String
并取消 KnownSymbol
约束,不知道它是如何工作的。