Haskell中的函数重载

Cri*_*cia 5 haskell overloading

我有一个结构,它表示形式中的线的方程m x + b和点的结构

Line { m :: Double, b :: Double } deriving( Show, Eq )
Point { x :: Double, y :: Double } deriving( Show, Eq )
Run Code Online (Sandbox Code Playgroud)

我想要perpendicular执行以下功能:

perpendicular (Line m b) (Point x y) = 
        Line m2 b2 where
                m2 = (-1/m)
                b2 = y - m2*x
Run Code Online (Sandbox Code Playgroud)

如果给定一条线和一条点,或者部分应用了一条线

perpendicular (Line m b) = 
        Line m2 where
                m2 = (-1/m)
Run Code Online (Sandbox Code Playgroud)

如果只给一条线.

这里的问题是我得到了

"垂直"的方程具有不同数量的参数

Cub*_*bic 12

Haskell在命令式语言中可能习惯的意义上没有函数重载; 如果允许,我甚至不确定类型推断是否仍然是可判定的.您可以获得的唯一类型的重载是类型类,尽管仍然不允许您定义带有不同数量参数的函数.

你的案例是一个很好的例子,说明为什么这在haskell中不起作用; 如果你有perpendicular someLine一个haskell编译器应该如何找出你正在谈论的这些函数?两者在这种情况下都是有效的,但表达式将根据所挑选的内容而具有不同的类型.

  • 实际上类型类*do*允许你定义带有不同数量参数的函数,就像`Text.Printf`模块那样.然而,它使类型推断变得相当脆弱,并且可能被认为是丑陋的黑客.对于这样的情况,这当然不合适. (2认同)

ham*_*mar 5

在第一种情况下,你想要的类型perpendicularLine -> Point -> Line,而在第二种情况下,你希望它有型Line -> Double -> Line。这表明我们可以使用类型类来做到这一点,在该类中抽象出第二个参数的类型:

class Perpendicular a where
  perpendicular :: Line -> a -> Line
Run Code Online (Sandbox Code Playgroud)

然后您的第一个案例成为 Point

instance Perpendicular Point where
  perpendicular (Line m b) (Point x y) = Line m2 b2
    where m2 = (-1/m)
          b2 = y - m2*x
Run Code Online (Sandbox Code Playgroud)

而第二个成为的实例Double

instance Perpendicular Double where
  perpendicular (Line m b) = Line m2
    where m2 = (-1/m)
Run Code Online (Sandbox Code Playgroud)