F#幻影类型在实践中

Fsh*_*ete 6 f# types

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

let combinePath (path : string) (fileName : string) = ...
Run Code Online (Sandbox Code Playgroud)

在我看来,幻影类型将是一个很好的方式来捕捉任何混乱.但我不明白如何在唯一的F#幻像类型问题中应用该示例.

在这个例子中我如何实现幻像类型?我怎么称呼combinePath?或者我错过了一个更简单的问题解决方案?

Pet*_*etr 12

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

type Path = Path of string
type Fname = Fname of string
let combinePath (Path(p)) (Fname(file)) = System.IO.Path.Combine(p, file)
Run Code Online (Sandbox Code Playgroud)

你可以这样称呼它

combinePath (Path(@"C:\temp")) (Fname("temp.txt"))
Run Code Online (Sandbox Code Playgroud)

  • 由于那些是一个案例的DU,你也可以``combinePath(Path(p))(Fname(f))= ...`,最终结果将是相同的:) (5认同)

kvb*_*kvb 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
Run Code Online (Sandbox Code Playgroud)