2009-04-08 40 views
1

因此,尚未:-)调整可识别联合对象

彼此区分工会问题的价值假设我有一个区分联合,像这样: -

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" 

凡你好= A( “你好”) 和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) 

正如这意味着我不得不每次添加一个新的联盟情况下的时间重新编写代码。

任何想法?

+0

你想为appendStringToFoo“x”(B(42))做什么行为?总的来说,这对我来说味道,你真正想做什么(什么是Foo/A/B)? – Brian 2009-04-08 23:58:03

+0

一般而言,“每次添加新的联合案例”时,您都必须重写使用该联合类型的所有世界中的代码。这是使用区分联合和使用类层次之间的折衷。 – Brian 2009-04-09 00:05:00

回答

2

你必须做你不想做的事情。

另一种方法是沿着线

  • 抽象类Foo
  • 抽象类StringyFoo:富{无效AppendString(字符串);字符串S; }
  • A类:StringyFoo
  • 类d:StringyFoo
  • 抽象类IntyFoo:富
  • 类B:IntyFoo

这潜在地避免了“固定起来appendString()每次添加一个新的令牌类型“,但我认为对于一个词法分析器(其中Foo =令牌),您会对DU的整体情况感到高兴。在一般情况下,无论您是使用类层次结构还是访问者模式,还是使用代数数据类型,您都必须为N个特征和M个子类型编写N * M个代码;有没有避免它,所以不要试图找到可爱的技巧,试图避免它,它只会导致痛苦。