Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 避免使用等效构造函数的样板代码_Haskell_Functional Programming - Fatal编程技术网

Haskell 避免使用等效构造函数的样板代码

Haskell 避免使用等效构造函数的样板代码,haskell,functional-programming,Haskell,Functional Programming,我的ADT如下所示: Prelude> data Bond = FixedRateBond Float Float | FloatingRateBond Float Float Prelude> let foo :: Bond -> Float Prelude| foo (FixedRateBond a b) = a + b Prelude| foo (FloatingRateBond a b) = a + b 我想在此ADT的每个值构造函数上执行一个操作,

我的ADT如下所示:

Prelude> data Bond = FixedRateBond Float Float | FloatingRateBond Float Float
Prelude> let foo :: Bond -> Float
Prelude|     foo (FixedRateBond a b) = a + b
Prelude|     foo (FloatingRateBond a b) = a + b
我想在此ADT的每个值构造函数上执行一个操作,如下所示:

Prelude> data Bond = FixedRateBond Float Float | FloatingRateBond Float Float
Prelude> let foo :: Bond -> Float
Prelude|     foo (FixedRateBond a b) = a + b
Prelude|     foo (FloatingRateBond a b) = a + b

正如您所看到的,我在这里有代码复制;对于我的每个值
a+b
。我将有更多的值构造函数,所以这将被重复更多。对我来说,这是代码的味道,但我不知道如何重构它以消除重复的代码。有没有一种功能性的方法来避免这种重复的代码?这是一个很小的例子,因为我已经把真正的问题简化为基本问题来解释问题。

你是对的。这是一种代码气味,实际上是一种非常常见的建模错误。你所需要做的就是把汇率类型计算出来。例如:

data RateType = Fixed | Floating

data Bond = Bond RateType Float Float
那你就有

foo :: Bond -> Float
foo (Bond _ a b) = a + b
除了其他好处之外,比如
RateType
现在实际上是一种类型,您可以使用
Enum
Bounded
实例


基本上,这里的经验法则是:如果您有多个构造函数实现同一个东西,那么必须有一个枚举要求进行分解。

在这种情况下,您可能是对的,但是,当构造函数上有+1个参数时,你会怎么做呢。@mb14这可能是一个信号,表明你有另一个较小的实体包装在那里,你需要进行更多的分解。使用
Float
通常是一个错误。在大多数情况下,您更可能希望
加倍。另一方面,在金融环境中,您有时需要定点。@dfeur,是的,我知道这只是一个虚拟示例来说明主要的设计问题。