说功能foo,bar noo是我程序的基础。此外,这些功能可以在不同的场景(foo1, bar1, foo2, bar2等)中以不同的方式实现,但仍然具有相同的输入foo1和foo2输出类型。根据一些输入或配置,程序foo1, bar1在某些场景下使用,而在另一种场景下,foo2, bar2.
我可以像上面描述的那样定义它们,将后缀 (1,2,3..) 附加到foo, bar, noo. 但是,这并不漂亮,因为后缀可能很长;它也不允许特殊绑定foo1with 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) {...};
}