我们可以在 Haskell 中定义一个 class 的函数定义吗?

Can we define a class of function definitions in Haskell?

对不起,我选择了这个标题,因为没有更好的词。

这是我感兴趣的函数定义模式的典型示例:

h1 :: (Integer, Integer) -> Integer
h1 (x, 0) = f1 x
h1 (x, n) = g1 (x, n)

h2 :: (Integer, Integer) -> Integer
h2 (x, 0) = f2 x
h2 (x, n) = g2 (x, n)

h3 :: (Integer, Integer) -> Integer
h3 (x, 0) = f3 x
h3 (x, n) = g3 (x, n)



f1 :: Integer -> Integer
f1 x = x
g1 :: (Integer, Integer) -> Integer
g1 (x, n) = x

f2 :: Integer -> Integer
f2 x = 0
g2 :: (Integer, Integer) -> Integer
g2 (x, n) = 0

f3 :: Integer -> Integer
f3 x = 2*x
g3 :: (Integer, Integer) -> Integer
g3 (x, n) = x*n

如您所见,第 1 行到第 11 行是重复的,并且展示了 h1、h2 和 h3 共有的函数定义方案(和类型)。该方案由以下定义完成。如果我可以说的话,第二部分包含实际的“定义内容”。

有没有办法定义一个 class 的函数定义来避免前 11 行的重复?

我希望我的问题有道理。

谢谢。

您可以构造一个辅助函数,将两个函数作为输入:fg,然后实现该模式。这样的助手看起来像:

helper :: (Eq b, Num b) => (a -> c) -> ((a, b) -> c) -> (a, b) -> c
helper <strong>f</strong> <strong>g</strong> = go
    where go (x, 0) = f x
          go xn = g xn

然后我们可以使用该模式来定义 h1h3:

h1 :: (Integer, Integer) -> Integer
h1 = <strong>helper</strong> f1 g1

h2 :: (Integer, Integer) -> Integer
h2 = <strong>helper</strong> f2 g2

h3 :: (Integer, Integer) -> Integer
h3 = <strong>helper</strong> f3 g3