Haskell 绑定到特定函数的标称类型

Haskell 绑定到特定函数的标称类型,haskell,types,f#,domain-driven-design,Haskell,Types,F#,Domain Driven Design,是否存在支持定义只能通过特定函数实例化的类型的语言或类型系统 例如,可以是绑定到函数CreateNonZeroInteger的类型NonZeroInteger。任何外部代码都可以访问该类型、接收和返回该类型的值。但至关重要的是,这种类型的值只能通过调用函数CreateNonZeroInteger来创建 非零整数应为名义类型。具有相同结构的另一类型的值不应与此类型相比较或可强制转换。创建一个类型,定义一个函数以创建该类型的值,然后导出该类型和函数,但不导出该类型的数据构造函数。例如,在Haskel

是否存在支持定义只能通过特定函数实例化的类型的语言或类型系统

例如,可以是绑定到函数CreateNonZeroInteger的类型NonZeroInteger。任何外部代码都可以访问该类型、接收和返回该类型的值。但至关重要的是,这种类型的值只能通过调用函数CreateNonZeroInteger来创建


非零整数应为名义类型。具有相同结构的另一类型的值不应与此类型相比较或可强制转换。

创建一个类型,定义一个函数以创建该类型的值,然后导出该类型和函数,但不导出该类型的数据构造函数。例如,在Haskell中,给出您的示例:

模块My.module.NonZeroInteger NonZeroInteger,createNonZeroInteger其中 newtype NonZeroInteger=非零整数 派生秀 createNonZeroInteger::Integer->可能是非零整数 createNonZeroInteger 0=Nothing createNonZeroInteger x=仅$NonZeroInteger x My.Module.NonZeroInteger的使用者将能够创建NonZeroInteger类型的值,但由于数据构造函数未导出,他们将永远无法创建内部为0的非零整数


自定义构造函数(在本例中为createNonZeroInteger)传统上称为。

创建一个类型,定义一个函数来创建该类型的值,然后导出该类型和您的函数,但不导出该类型的数据构造函数。例如,在Haskell中,给出您的示例:

模块My.module.NonZeroInteger NonZeroInteger,createNonZeroInteger其中 newtype NonZeroInteger=非零整数 派生秀 createNonZeroInteger::Integer->可能是非零整数 createNonZeroInteger 0=Nothing createNonZeroInteger x=仅$NonZeroInteger x My.Module.NonZeroInteger的使用者将能够创建NonZeroInteger类型的值,但由于数据构造函数未导出,他们将永远无法创建内部为0的非零整数


自定义构造函数(在本例中为createNonZeroInteger)传统上称为a。

我认为这里值得记录在案的是,您可以通过将union case构造函数设置为私有来执行与Alexis King在F中建议的完全相同的操作


类型本身仍然可以公开访问,但它只能通过您提供的函数来创建和分解。

我认为值得记录在案的是,您可以通过将union case构造函数私有化来完成与Alexis King在F中建议的完全相同的事情


类型本身仍然可以公开访问,但只能通过您提供的函数来创建和分解它。

我认为这通常是通过一个模块来完成的,该模块隐藏数据构造函数并公开一个封装数据构造函数的函数。请看这里的最上面的答案:在f中,您可以使用访问修饰符,但如果有一种语言或类型系统支持定义只能通过特定函数实例化的类型,那就太糟糕了。嗯,C++为一;但我不知道有哪一个基于Hindley–Milner的类型系统能够完全支持它,这似乎是您实际要求的。我认为这通常是通过隐藏数据构造函数并公开封装数据构造函数的函数的模块来实现的。请看这里的最上面的答案:在f中,您可以使用访问修饰符,但如果有一种语言或类型系统支持定义只能通过特定函数实例化的类型,那就太糟糕了。嗯,C++为一;但我不知道有哪一个基于Hindley–Milner的类型系统能够完全支持它,这似乎是你真正想问的。我真的希望类型本身绑定到签名中的函数,而不是利用模块封装。但这确实很有帮助,并且回答了这个问题。我真的希望类型本身绑定到签名中的函数,而不是利用模块封装。但这确实很有帮助,并且回答了这个问题。
type NonZeroInteger = private NonZeroInteger of int

let tryCreateNonZeroInteger = function
    |0 -> None
    |x -> Some <| NonZeroInteger x