说功能foo
,bar
noo
是我程序的基础。此外,这些功能可以在不同的场景(foo1, bar1
, foo2, bar2
等)中以不同的方式实现,但仍然具有相同的输入foo1
和foo2
输出类型。根据一些输入或配置,程序foo1, bar1
在某些场景下使用,而在另一种场景下,foo2, bar2
.
我可以像上面描述的那样定义它们,将后缀 (1,2,3..) 附加到foo, bar, noo
. 但是,这并不漂亮,因为后缀可能很长;它也不允许特殊绑定foo1
with bar1
(vs. bar2
)。
另一种方法是将每个场景视为单独的Module
. 现在foo, bar, noo
对于每个案例都很好地结合在一起,并且避免了丑陋的后缀。但是,当每个Module
. 这种方法的另一个缺点是它们Modules
是完全分开的,即使它们确实有一些相似之处(例如三个功能)。
一个typeclass
解决方案将不胜感激,但我并没有想到,因为不同场景foo
的不同s具有相同的输入和输出。
我想知道是否有针对该问题的 Haskell 最佳实践来避免这些方法的上述缺点。
foo1 :: Double -> Double
bar1 :: Int -> Int
noo1 :: [Int] -> [Int]
foo2 :: Double -> Double
bar2 :: Int -> Int
noo2 :: [Int] -> [Int]
...
foo9 :: Double -> Double
bar9 :: Int -> Int
noo9 :: [Int] -> [Int]
编辑:我想这与讨论有关,以解释我将如何处理它Java Interface
(一些不错的,但概念级别的讨论,Java interface
可以Haskell typeclass
在这篇文章和这里找到。)Java interface and class
在许多情况下可能很复杂,但在这里重载实际上很简洁。
interface Scenario {
double foo(double d);
int bar(int i);
Array<int> noo(Array<int> a);
}
class UseScenario {
void use(Scenario ss) {
ss.foo(...);
ss.bar(...);
ss.noo(...);
}
}
class S1 implements Scenario {
double foo(double d) {...};
int bar(int i) {...};
Array<int> noo(Array<int> a) {...};
}
class S2 implements Scenario {
double foo(double d) {...};
int bar(int i) {...};
Array<int> noo(Array<int> a) {...};
}