首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Haskell中的简单细化类型

Haskell中的简单细化类型
EN

Stack Overflow用户
提问于 2020-07-07 20:50:20
回答 1查看 219关注 0票数 1

从Scott的博客帖子和Book的“域建模使功能”和Alexis King的帖子中,我认为域模型应该编码尽可能多的域信息,以便“使非法状态无法表示”,并获得强大的保证,使我能够编写全面的域逻辑函数。

在基本的企业应用程序中,我们有许多基本的域类型,如街道名称、公司名称、城市等等。若要将它们表示为防止以后出现大多数错误的形式,我希望使用允许我使用的类型。

  • 限制最大和最小字符数。
  • 指定可以使用的字符子集,
  • 添加其他约束,例如没有前导或尾随空格。

我可以想出两种实现这类类型的方法:使用智能构造函数和隐藏数据构造函数的自定义抽象数据类型,或者通过某种类型级别的机器(我模糊地读到了细化类型?这些类型可以通过一些较新的语言扩展来表示吗?通过LiquidHaskell?)哪一条路是明智的?哪种方法最容易与在常规Text上操作的所有函数一起工作,我如何才能最容易地组合两个或多个相同精化类型的值,并对它们进行映射等等?

理想情况下,应该有一个库来帮助我创建这样的自定义类型。在那里吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-07-09 12:44:03

在Alexis的博客之后,我想说一个合适的解决方案如下所示。当然,其他解决方案也是可行的。

代码语言:javascript
复制
import Control.Monad (>=>)

newtype StreetName = StreetName {getStreetName :: String}

-- compose all validations and wrap them in new constructor.
asStreetName :: String -> Maybe StreetName
asStreetName = StreetName <$> rightNumberOfChars >=> rightCharSubset >=> noTrailingWhiteSpace

-- This funcs will process the string, and produce another validated string or nothing. 
rightNumberOfChars :: String -> Maybe String
rightNumberOfChars s = {- ... -}

rightCharSubset :: String -> Maybe String
rightCharSubset s = {- ... -}

noTrailingWhiteSpace :: String -> Maybe String
noTrailingWhiteSpaces = {- ... -}

main = do
  street <- readStreetAsString
  case asStreetName street of
    Just s  -> {- s is now validated -}
    Nothing -> {- handle the error -}

StreetName成为隐藏的构造函数,就像使用asStreetName作为智能构造函数一样。请记住,其他函数应该在类型中使用StreetName而不是String,以确保数据得到验证。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62783722

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档