记录语法:验证构造函数中的内容 [英] Record syntax: validate contents in constructor

查看:89
本文介绍了记录语法:验证构造函数中的内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个有12个值的记录。有一些无效值的组合,所以我想要构造函数来检查它。我只知道如何制作带有参数列表的构造函数,但对于12个值来说,这并不是很漂亮。因此,我希望在构造它时使用该值时使用记录语法。



如何在构造函数中强制约束并仍使用记录语法?

解决方案

我将以更详细的方式发布我的第一条评论,也许你会发现这个不错。

首先,假设您的数据看起来或多或少像这样:

  data MyBigData = MyBigData {
a :: ...
b :: ...
...
z :: ...
}

的确,用智能构造函数代替时,您无法解决这个问题。



然而,假设你的库函数看起来或多或少像这样:

pre $ libFun :: MyBigData - >结果

我提出以下解决方案。创建一个包装类型:

  newtype ValidData = ValidData MyBigData 

不要导出其构造函数。将你的函数改为:

  libFun :: ValidData  - >结果
libFun(ValidData d)= ...

然后将验证逻辑放入函数:

  validate :: MyBigData  - >也许有效数据

现在当调用 validate 时,您可以使用记录语法,但是如果你不首先验证它,你将无法在任何实际期望它处于一致状态的函数中使用这些数据。



<$ p $ input = validate $ MyBigData {...}
输入的情况:
Just d - > libFun d
Nothing - > ...

当然在这种情况下 validate 也可以返回或者,或者如果你需要的话可能会单调行事。


I have a record with 12 values. There are a few combinations of values that are not valid, so I would like the constructor to check this. I only know how to make constructors that take a list of arguments, but that's not very pretty with 12 values. Thus, I would like to use record syntax when using the value after having constructed it.

How do I enforce constraints in the constructor(s) and still use record syntax?

解决方案

I'm going to post my first comment in a bit more elaborated way, and maybe you'll find this good enough.

First, let's assume your data looks more or less like this:

data MyBigData = MyBigData {
   a :: ...
   b :: ...
   ...
   z :: ...
}

Indeed, when replaced with smart constructor, you can't do much about that problem.

However, assuming your library functions look more or less like this:

libFun :: MyBigData -> Result

I propose the following solution. Create a wrapping type:

newtype ValidData = ValidData MyBigData

Don't export its constructor. Change your functions to:

libFun :: ValidData -> Result
libFun (ValidData d) = ...

And put the validation logic in a function:

validate :: MyBigData -> Maybe ValidData

Now when calling validate you can use record syntax, but you won't be able to use this data in any function that actually expects it in coherent state if you don't validate it first.

input = validate $ MyBigData { ... }
case input of:
    Just d -> libFun d
    Nothing -> ...

Of course in this case validate could also return Either or perhaps act monadically if you need that.

这篇关于记录语法:验证构造函数中的内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆