我希望F#函数中的参数具有特定类型:
type NewType = string*int
let testFunction (arg1:NewType) : NewType =
("resultString", 2)
testFunction ("test", 3)
我希望函数的类型为:
NewType -> NewType
但功能类型是:
string*int -> NewType
如何将参数arg1的类型强制为“NewType”?
答案 0 :(得分:4)
NewType
的类型声明是一个类型别名,意味着NewType
可以与string * int
交换 - 编译器将它们视为同一个东西,有时这意味着它会报告一个尽管有类型注释,但代替了另一个。
如果您想要一个始终必须通过其全名引用的类型,您需要将其定义为显式新类型 - 此时,最好使用记录(这也可以让你为各个字段命名),但如果你想要一些简洁的话,你可以使用一个单一案例的歧视联盟:
type NewType = NT of (string*int)
let testFunction (NT arg1) : NewType =
NT("resultString", 2)
testFunction (NT("test", 3))
答案 1 :(得分:4)
type NewType = string * int
是所谓的类型缩写。它为另一种类型提供名称或别名,但在编译期间会被删除。没有封装,没有新的参考,基本上没有新的类型。
它可以作为文档,但F#的编译器将新名称和别名类型视为相同。如果您使用公共函数/方法创建一个使用NewType
并尝试从另一个项目调用它的DLL,则尤其可见 - 您将看到类似于您的情况的混合结果。
如果你想要实现的只是更好的可读性,这可能不是问题。如果我在代码中看到let testFunction (arg1:NewType) : NewType = ...
,特别是在GitHub上的网络上,那里没有智能感知工具提示,这仍然让我非常清楚函数采取和返回的内容,即使"真实&# 34;实践中的类型是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/