Types F#实践中的幻影类型

Types F#实践中的幻影类型,types,f#,Types,F#,我经常有一个具有多个相同类型参数的函数,有时会以错误的顺序使用它们。举个简单的例子 let combinePath (path : string) (fileName : string) = ... 在我看来,幻影类型将是捕捉任何混乱的好方法。但我不明白如何将这个例子应用到唯一的例子中 在本例中,我将如何实现幻影类型?我怎么称呼combinePath?还是我错过了一个更简单的解决方案?我认为最简单的方法是使用歧视性工会: type Path = Path of string type Fnam

我经常有一个具有多个相同类型参数的函数,有时会以错误的顺序使用它们。举个简单的例子

let combinePath (path : string) (fileName : string) = ...
在我看来,幻影类型将是捕捉任何混乱的好方法。但我不明白如何将这个例子应用到唯一的例子中


在本例中,我将如何实现幻影类型?我怎么称呼combinePath?还是我错过了一个更简单的解决方案?

我认为最简单的方法是使用歧视性工会:

type Path = Path of string
type Fname = Fname of string
let combinePath (Path(p)) (Fname(file)) = System.IO.Path.Combine(p, file)
你可以这样说

combinePath (Path(@"C:\temp")) (Fname("temp.txt"))

我同意Petr的观点,但为了完整起见,请注意,只有当您有一个泛型类型可以使用幻影类型时,才可以使用幻影类型,因此您不能对纯
字符串
输入执行任何操作。相反,您可以这样做:

type safeString<'a> = { value : string }

type Path = class end
type FileName = class end

let combinePath (path:safeString<Path>) (filename:safeString<FileName>) = ...

let myPath : safeString<Path> = { value = "C:\\SomeDir\\" }
let myFile : safeString<FileName> = { value = "MyDocument.txt" }

// works
let combined = combinePath myPath myFile

// compile-time failure
let combined' = combinePath myFile myPath

type safestring由于这些是一种情况下的DU,您也可以执行
let combinePath(Path(p))(Fname(f))=…
,最终结果将是相同的:),这意味着为每个参数类型声明一个类型。我想我在想它可能有点像度量单位,弦。虽然它仍然需要路径和文件名的类型,所以最终还是一样的。。。回答我自己的问题。@Fsharp-Pete:我认为这些参数无论如何都是不同的字符串类型。如果您不声明它们,您的程序很容易出错(例如,文件名字符串不能包含符号“\”,但路径字符串可以),显式声明它们您可以添加验证等。看看好的资源:显然,有区别的联合是更好的方法。幻影类型对于F#来说似乎是多余的。我想这就是为什么没有太多报道的原因。@FsharpPete-我认为这不太正确;在这个特定的场景中,DU可能更好,但肯定有幻影类型有用的场景(我不认为F#在何时使用一种或另一种技术方面与大多数其他语言有明显的不同)。是的,我现在看到了。使用幻像类型方法,您可以从模块/包外部指定幻像类型,而不是使用区分的联合。