F#函数参数类型注释不起作用

时间:2017-09-26 17:22:48

标签: function f# arguments type-annotation

我希望F#函数中的参数具有特定类型:

type NewType = string*int

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

testFunction ("test", 3)

我希望函数的类型为:

NewType -> NewType

但功能类型是:

string*int -> NewType

如何将参数arg1的类型强制为“NewType”?

2 个答案:

答案 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/