haskell - 如何在Haskell中创建包含有限长度字符串的类型

标签 haskell

Possible Duplicate:
How to make a type with restrictions

是否可以在 Haskell 中创建一个类型,例如“Name”,它是一个字符串,但包含不超过 10 个字母?

如果不是,我如何禁止创建一个具有长名称的人(其中人的定义如下: data Person = Person Name )。

也许这根本不重要,也许这类问题应该在 Haskell 中以不同的方式解决?

最佳答案

不要从定义类型的模块中导出构造函数,而是导出“智能构造函数”:

module Name (Name(), -- exports the type Name, but not the data constructor Name
             nameFromString,
             stringFromName)
where

data Name = Name String

-- this is the only way to create a Name
nameFromString :: String -> Maybe Name
nameFromString s | 10 < length s = Nothing
                 | otherwise     = Just (Name s)

-- this is the only way to access the contents of a Name
stringFromName :: Name -> String
stringFromName (Name s) = s
<小时/>

因此,您担心如果您以前的代码不要求名称限制为十个字符,则不能直接放入 nameFromString,因为它的类型为 String -> 也许名称 而不是字符串 -> 名称

首先,如果你确实想抛出异常,可以定义

import Data.Maybe (fromMaybe)

nameFromString' :: String -> Name
nameFromString' = fromMaybe (error "attempted to construct an invalid Name") . nameFromString

并使用它来代替。

其次,抛出异常有时是错误的做法。考虑一下

askUserForName :: IO Name
askUserForName
   = do putStr "What's your name? (10 chars max)  "
        s <- getLine
        case nameFromString s of
            Just n  -> return n
            Nothing -> askUserForName

重写它以使用异常会导致更复杂的代码。

关于haskell - 如何在Haskell中创建包含有限长度字符串的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10457538/

相关文章:

list - Haskell - 列表中累积的总和

haskell - 带 fclabel 的 STM

haskell - 基于类型级别谓词的实例?

haskell - 类型类 "between"类别和箭头有意义吗?

haskell - 处理 `ExceptT` 计算中的不同错误类型

Haskell GHC : what is the time complexity of a pattern match with N constructors?

list - 过滤列表列表中的元组 [Haskell]

haskell - 对于明显相等的实例定义,类型检查失败

haskell - HDBC-ODBC SQL Server 需要在快速查询后提交

haskell - 包含导入 Gloss 的项目时 `stack ghci` 失败