3

我想为 F# 函数中的参数指定一个特定类型:

type NewType = string*int

let testFunction (arg1:NewType) : NewType =
  ("resultString", 2)

testFunction ("test", 3)

我希望函数的类型是:

NewType -> NewType

但是函数类型是:

string*int -> NewType

我应该怎么做才能强制参数 arg1 的类型为“NewType”?

4

2 回答 2

4

的类型声明NewType是一个类型别名,这意味着它NewType可以交换string * int- 编译器将它们视为相同的东西,有时这意味着它会报告一个代替另一个,尽管有类型注释。

如果您想要一个始终必须通过其全名引用的类型,您需要将其定义为显式的新类型 - 此时,最好使用记录(这也可以让您命名个人字段),但如果你想要一些简洁的东西,你可以使用单例区分联合代替:

type NewType = NT of (string*int)

let testFunction (NT arg1) : NewType =
  NT("resultString", 2)

testFunction (NT("test", 3))
于 2017-09-26T17:36:52.253 回答
4

type NewType = string * int就是所谓的类型缩写。它为另一种类型提供名称或别名,但在编译过程中会被删除。没有封装,没有新的引用,也基本没有新的类型。

它可以用作文档,但 F# 的编译器将新名称和别名类型视为相同。如果您使用正在使用的公共函数/方法创建 DLLNewType并尝试从另一个项目中调用它,则这一点尤其明显 - 您将看到与您的情况类似的混合结果。

如果您想要实现的只是更好的可读性,这可能不是问题。如果我let testFunction (arg1:NewType) : NewType = ...在代码中看到,尤其是在 GitHub 等网络上,没有 IntelliSense 工具提示,这仍然让我很好地了解函数接受和返回的内容,即使实践中的“真实”类型是string * int.

如果您想要更好的类型安全性,通常的做法是定义一个单例区分联合,您可以将其与模式匹配结合起来,如下所示:

type NewType = NewType of (string * int)

let testFunction (NewType arg1): NewType =
    NewType ("resultString", 2)

testFunction (NewType ("test", 3))

您可以在此处以及该系列的其他文章中阅读更多内容:https ://fsharpforfunandprofit.com/posts/type-abbreviations/

于 2017-09-26T17:39:11.357 回答