F#型系统可以这样做吗?

我有很多种有共同目的的类型,但没有其他共同之处.为了便于解释,它们可能也是如此:

type blah<'a> = Blah of 'a

type huha<'a> = Huha of 'a

我经常需要重复一大块样板文件,这些样板文件可能会沿着以下方式进入函数:

let f (x:something<int>) (g:something<char> -> float) : float =

但这需要以某种方式强制执行该类型中的两个事件是相同的.换句话说,我希望能够将函数f称为:

f (Blah 1) (fun (b:blah<float>) -> .... )
f (Huha 1) (fun (b:huha<float>) -> .... )

显然,一个简单的解决方案是创建函数f可能采用的所有类型的区别联合,并使每个g(即f的第二个参数)检查它得到它预期的任何类型.但这意味着拥有一个庞大的类型,导致Universe每次发生任何变化时都会重新编译,而且它不像在运行时检查类型也有很大帮助.

那么,有人可以通过类型安全的方式看到我想要的方式吗?非常感谢.

最佳答案 据我了解,你不能直接在F#中这样做.

但也许操作符超载会有所帮助.但是,您必须为每种类型实现f.但也许你可以委托一个共同的实现.

运算符重载的代码示例,确保正确的类型:

type T<'a> =
   | T of 'a
   static member (.+.) (l:T<int>, r:T<char> -> float) = 42.0

type U<'a> =
   | U of 'a
   static member (.+.) (l:U<int>, r:U<char> -> float) = 13.1


let ft (t:T<char>) = 42.0

let fu (t:U<char>) = 42.0

let t = T 42 .+. ft
let u = U 13 .+. fu

// does not compile:
let wrong = T 42 .+. fu
点赞