【发布时间】:2009-04-08 22:23:38
【问题描述】:
所以,又是一个受歧视的工会问题 :-)
假设我有一个像这样的有区别的联合:-
type Foo =
| A of string
| B of int
| C of char
| D of string
我希望能够使用一个函数,appendStringToFoo,如下:-
let someVal = A("hi")
let anotherVal = D("yo")
let hiya = someVal |> appendStringToFoo "ya"
let yoyo = anotherVal |> appendStringToFoo "yo"
hiya = A("hiya") 和 yoyo = D("yoyo")。
显然,我还会继续编写单独的函数 appendIntToFoo、appendCharToFoo 等。
所以,实际上,一个类似于以下的函数:-
let appendStringToFoo str fooValue =
fooValue(fooValue.Value + str)
这似乎不可能。
如果可以避免的话,我不想做以下事情:-
let appendStringToFoo str fooValue =
match fooValue with
| A(originalStr) -> A(originalStr + str)
| D(originalStr) -> D(originalStr + str)
因为这意味着我每次添加新的联合案例时都必须重新编写这段代码。
有什么想法吗?
【问题讨论】:
-
您希望 appendStringToFoo "x" (B(42)) 有什么行为?总的来说,这对我来说很奇怪,你真正想做什么(什么是 Foo/A/B)?
-
一般来说,“每次你添加一个新的联合案例”你必须重写世界上所有使用那个联合类型的代码。这是使用可区分联合和使用类层次结构之间的权衡。
-
这是词法分析器的一部分;我正在从字符构造一个字符串,该字符串被放置在令牌的可区分联合表示中。
-
无论如何我已经重构了这个(是的,它确实有味道!)。在回答您的问题时,我曾打算在这种情况下导致某种异常;然而,经过反思,它似乎相当不安全。现在我想再次匹配 'a -> DiscrimUnion 的问题......!
标签: f#