F# 中的重载运算符:(/)
我想在 F# 中重载字符串的 (/) 运算符并保留数字的含义。
/// Combines to path strings
let (/) path1 path2 = Path.Combine(path1,path2)
let x = 3 / 4 // doesn't compile
如果我尝试以下操作,我会收到“警告 29 扩展成员无法提供运算符重载。请考虑将运算符定义为类型定义的一部分。”
/// Combines to path strings
type System.String with
static member (/) (path1,path2) = Path.Combine(path1,path2)
有什么想法吗?
问候, 福尔基
I would like to overload the (/) operator in F# for strings and preserve the meaning for numbers.
/// Combines to path strings
let (/) path1 path2 = Path.Combine(path1,path2)
let x = 3 / 4 // doesn't compile
If I try the following I get "Warning 29 Extension members cannot provide operator overloads. Consider defining the operator as part of the type definition instead."
/// Combines to path strings
type System.String with
static member (/) (path1,path2) = Path.Combine(path1,path2)
Any ideas?
Regards,
forki
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您无法为现有类型提供重载运算符。一种选择是使用另一个运算符名称(如 Natahan 建议的那样)。但是,您还可以定义一种新类型来表示 F# 代码中的路径,并为此类型提供
/
运算符:这有一个重要的好处 - 通过使类型更加明确,您可以为类型检查器提供帮助它可以用来验证您的代码的更多信息。如果您使用字符串来表示路径,那么您很容易将路径与其他字符串(例如名称)混淆。如果您定义了
Path
类型,类型检查器将防止您犯此错误。此外,编译器不会允许您(简单地)错误地组合路径(如果您将路径表示为字符串,则很容易发生这种情况),因为
p + p
未定义(您只能使用/
,它正确使用了Path.Combine
)。You cannot provide overloaded operators for existing types. One option is to use another operator name (as Natahan suggests). However, you can also define a new type to represent paths in your F# code and provide the
/
operator for this type:This has one important benefit - by making the types more explicit, you give the type checker more information that it can use to verify your code. If you use strings to represent paths, then you can easily confuse path with some other string (e.g. name). If you define your
Path
type, the type-checker will prevent you from making this mistake.Moreover, the compiler won't allow you to (simply) combine paths incorrectly (which can easily happen if you represent paths as strings), because
p + p
is not defined (you can use only/
, which correctly usesPath.Combine
).我认为没有直接的方法可以做到这一点。 F# 中的运算符重载不考虑扩展成员,并且没有使用成员约束以半通用方式重新定义操作的好方法。
可以将一些可行的东西组合在一起,但它非常丑陋:
I don't think that there is a straightforward way to do that. Extension members aren't taken into consideration for operator overloading in F#, and there isn't a good way to redefine the operation in a semi-generic way using member constraints.
It is possible to hack something together that will work, but it's very ugly:
其实你可以。
试试这个:
Actually you can.
Try this:
根据对重载文档的阅读,我认为这在 F# 中是不可能的/a>.
相反,我建议您创建自己的函数,它看起来像
/
但事实并非如此。类似于:从长远来看,这可能不会那么烦人,因为它不会干扰人类读者正在运行的隐式类型推断 -
/
意味着结果是浮点,记住有时它是一个字符串是一种负担*。但读者第一次看到后,很容易记住它做了一些与嵌入中间的符号相关的事情。
*我认为
+
字符串看起来不错的唯一原因是过度曝光。长期使用 Haskell 或 Caml 后,切换到另一种语言后的前几分钟会让"foo" + "bar"
看起来非常糟糕。I do not think this is possible in F#, based on a reading of the overloading documentation.
I would instead suggest that you create your own function which looks like
/
but isn't. Something like:This is likely to be less annoying in the long run because it doesn't mess with the implicit type inference that the human reader is running--
/
means that the result is a floating point, and remembering that it's sometimes a string is a burden*. But after the first time the reader sees</>
, it's easy to remember that it does something related to the symbol embedded in the middle.*I think the only reason
+
for strings looks OK is over-exposure. After using Haskell or Caml for a long time, the first few minutes after switching to another language makes"foo" + "bar"
look jarringly bad.