for*_*i23 13 f# inline operator-overloading
我想重写F#中的(/)运算符以获取字符串并保留数字的含义.
/// Combines to path strings
let (/) path1 path2 = Path.Combine(path1,path2)
let x = 3 / 4 // doesn't compile
Run Code Online (Sandbox Code Playgroud)
如果我尝试以下操作,我会得到"警告29扩展成员无法提供操作员重载.请考虑将操作符定义为类型定义的一部分."
/// Combines to path strings
type System.String with
static member (/) (path1,path2) = Path.Combine(path1,path2)
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?
此致,forki
Tom*_*cek 20
您无法为现有类型提供重载运算符.一种选择是使用另一个运营商名称(如Natahan建议的那样).但是,您还可以定义一个新类型来表示F#代码中的路径,并/为此类型提供运算符:
open System
// Simple type for representing paths
type Path(p) =
// Returns the path as a string
member x.Path = p
// Combines two paths
static member ( / )(p1:Path, p2:Path) =
Path(IO.Path.Combine(p1.Path, p2.Path))
let n = 4 / 2
let p = Path("C:\\") / Path("Temp")
Run Code Online (Sandbox Code Playgroud)
这有一个重要的好处 - 通过使类型更明确,您可以为类型检查器提供更多可用于验证代码的信息.如果使用字符串表示路径,则可以轻松地将路径与其他字符串(例如名称)混淆.如果您定义了Path类型,则类型检查器将阻止您犯这个错误.
此外,编译器不允许您(简单地)错误地组合路径(如果您将路径表示为字符串,这很容易发生),因为p + p未定义(您可以仅使用/,正确使用Path.Combine).
Gus*_*Gus 10
其实你可以.
试试这个:
open System.IO
type DivExtension = DivExtension with
static member inline (=>) (x , DivExtension) = fun y -> x / y
static member (=>) (x , DivExtension) = fun y -> Path.Combine(x, y)
static member (=>) (x:DivExtension, DivExtension) = fun DivExtension -> x
let inline (/) x y = (x => DivExtension) y
Run Code Online (Sandbox Code Playgroud)
我认为没有一种直接的方法可以做到这一点.F#中的运算符重载不考虑扩展成员,并且没有一种使用成员约束以半通用方式重新定义操作的好方法.
可以将可以工作的东西混在一起,但它非常丑陋:
type DivisionOperations =
static member Divide(x:int, y:int) = x / y
static member Divide(path1, path2) = Path.Combine(path1, path2)
let inline div< ^t, ^a, ^b, ^c when (^t or ^a) : (static member Divide : ^a * ^b -> ^c)> a b = ((^t or ^a) : (static member Divide : ^a * ^b -> ^c) (a, b))
let inline (/) x y = div<DivisionOperations, _, _, _> x y
Run Code Online (Sandbox Code Playgroud)
基于对重载文档的阅读,我不认为这在F#中是可行的.
我建议你创建自己的功能,看起来像 /但不是.就像是:
let (</>) path1 path2 = Path.Combine (path1,path2)
Run Code Online (Sandbox Code Playgroud)
从长远来看,这可能不那么烦人,因为它不会弄乱人类读者正在运行的隐式类型推断 - /意味着结果是一个浮点,并且记住它有时是一个字符串是一个负担*.但是在读者第一次看到之后</>,很容易记住它与嵌入在中间的符号有关.
*我认为+字符串看起来不错的唯一原因是过度曝光.在使用Haskell或Caml很长一段时间后,切换到另一种语言后的前几分钟"foo" + "bar"看起来很糟糕.