当前位置:  开发笔记 > 编程语言 > 正文

键入表示非空的字符串或F#中的空格

如何解决《键入表示非空的字符串或F#中的空格》经验,为你挑选了1个好方法。

我喜欢简单的类型

type Code = Code of string

但我想对字符串设置一些限制(在这种情况下 - 不允许空格仅限字符串).就像是

type nonemptystring = ???
type Code = Code of nonemptystring

如何用F#惯用法定义这种类型?我知道我可以使用构造函数或带有工厂函数的受限模块使其成为一个类,但是有一个简单的方法吗?



1> Mark Seemann..:

A string本质上是一系列char值(在Haskell中,BTW,String 一个类型别名[Char]).那么,更普遍的问题是,是否可以静态地将列表声明为具有给定大小.

这种语言特征被称为依赖类型,而F#没有它.因此,简短的回答是,这不可能以声明的方式进行.

那么,最简​​单的,也可能是最惯用的方式是定义Code为单一案例的歧视联盟:

type Code = Code of string

在定义的模块中Code,您还可以定义客户端可用于创建Code值的函数:

let tryCreateCode candidate =
    if System.String.IsNullOrWhiteSpace candidate
    then None
    else Some (Code candidate)

此函数包含阻止客户端创建空Code值的运行时逻辑:

> tryCreateCode "foo";;
val it : Code option = Some (Code "foo")
> tryCreateCode "";;
val it : Code option = None
> tryCreateCode "   ";;
val it : Code option = None

什么阻止客户端创建无效Code值呢?例如,客户端是否能够绕过该tryCreateCode功能并简单地写Code ""

这是签名文件的来源.您创建一个签名文件(.fsi),并在其中声明类型和函数,如下所示:

type Code
val tryCreateCode : string -> Code option

这里Code声明了类型,但它的'构造函数'不是.这意味着您无法直接创建此类型的值.例如,这不编译:

Code ""

给出的错误是:

错误FS0039:未定义值,构造函数,命名空间或类型"代码"

创建Code值的唯一方法是使用该tryCreateCode函数.

如此处所示,您不能再访问基础字符串值Code,除非您还提供了以下函数:

let toString (Code x) = x

并在与.fsi上面相同的文件中声明它:

val toString : Code -> string

这可能看起来像很多工作,但实际上只有六行代码和三行类型声明(在.fsi文件中).


不会将类型构造函数设为私有吗?`type Code =字符串的私有代码`
推荐阅读
N个小灰流_701
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有