我的代码看起来像
type U0 = E1|E2|E3...
type T2 = {field1: string; field2: string; field3: string}
type T1 = T2*T2*T2
type T0 = T1*T1*T1
我想对P1
field1
的{{1}}类型强制执行一些谓词field1
,(GetUnionCases typeof<U0>).contains(field1)
。我希望这不是太抽象。
所以要做到这一点,我想介绍类型P1,其定义类似于
type P1(x) = (GetUnionCases typeof<U0>).map(fun x -> x.Name).contains(x)
答案 0 :(得分:2)
通常,F#没有任何形式的refinement types可以让任意谓词作为约束来附加类型声明。
很难根据您的抽象示例给出更具体的答案,但通常情况下,可以不同地设计域(您的类型),以便通过构造强制执行谓词 - 换句话说,设计您的类型,以便该类型的任何值自动满足谓词。 designing with types article series有一些实际的例子表明了这一点。
我没有完全按照您的示例,但是您要确保field1
字符串包含值E1
,字符串field2
包含值E2
(作为子字符串)等等。所以:
{ field1 = "hi E1 there" } // valid
{ field1 = "hi there" } // invalid
您可以将field1
的类型从string
更改为string * string
,表示前缀和字符串“E1”的后缀,因此您只能构建:
{ field1 = "hi", "there" } // valid
现在无法创建一个不隐含“E1”作为子字符串的值!
我很确定我误解了你的例子,但我希望这能证明这个想法......