我经常有一个具有相同类型的多个参数的函数,有时会以错误的顺序使用它们。作为一个简单的例子
let combinePath (path : string) (fileName : string) = ...
在我看来,幻影类型将是一个很好的方法来捕捉任何混乱。但我不明白如何仅在F# phantom types question中使用该示例。
如何在此示例中实现幻像类型?我怎么称呼combinePath?或者我错过了一个更简单的问题解决方案?
答案 0 :(得分:12)
我认为最简单的方法是使用受歧视的工会:
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"))
答案 1 :(得分:7)
我同意Petr的观点,但为了完整起见,请注意,当您使用通用类型时,您只能使用幻像类型,因此您无法对平原做任何事情string
输入。相反,你可以这样做:
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