在Elm中何时使用类型别名与单值联合类型

在Elm中何时使用类型别名与单值联合类型,elm,type-alias,union-types,Elm,Type Alias,Union Types,我一直在阅读,我看到了很多类似的事情: type Username = Username String type alias Username = String 我不确定使用这样的东西是否有意义,单值联合类型,而不是像这样的类型别名: type Username = Username String type alias Username = String 什么时候使用单值联合类型与只使用类型别名是合适的?对于什么时候合适没有硬性规定,但我倾向于遵循一些经验

我一直在阅读,我看到了很多类似的事情:

type Username
    = Username String
type alias Username
    = String
我不确定使用这样的东西是否有意义,单值联合类型,而不是像这样的类型别名:

type Username
    = Username String
type alias Username
    = String

什么时候使用单值联合类型与只使用类型别名是合适的?

对于什么时候合适没有硬性规定,但我倾向于遵循一些经验法则。让我们使用一个authenticate函数示例,它接受用户名和密码,两者都是字符串值

至少在没有任何其他别名或类型的情况下,注释可以是:

authenticate:String->String->Bool
根据该注释,不清楚哪个参数是用户名,哪个参数是密码。我们可以通过使用类型别名来提高可读性:

type alias Username=String
键入alias Password=String
验证:用户名->密码->Bool
这对我的包的使用者来说更好,但是类型别名不会禁止您在调用代码时意外地交换参数。例如,此有问题的函数将编译:

登录:用户名->密码->Bool
登录用户名密码=
如果验证密码用户名,则。。。
如果您想更进一步,并在每次使用类型时强制显式声明该类型,则可以避免该类型的错误,因为编译器将捕获混淆:

type Username=用户名字符串
键入密码=密码字符串
根据该定义,您现在必须在每次使用用户名或密码构造函数时显式地将字符串展开并打包到用户名或密码构造函数中。这对于度量单位之类的东西特别有用,因为这样一个概念可能有


正如您在Richard的示例中所看到的,使用完整类型和类型构造函数意味着您将需要单独的样板函数来进行json解码、编码等,这可能会变得单调乏味。您需要为您的团队和项目找到适当的平衡。

您所展示的示例被称为不透明类型。使用其中一个选项可以对程序的其他部分隐藏实现细节(对于库,则对使用者隐藏)。您可以在中阅读有关它们的更多信息(请参阅标题为“保留标记和记录构造函数机密”的部分)。