Haskell中的函数重载

时间:2014-05-26 07:50:30

标签: haskell overloading

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

Line { m :: Double, b :: Double } deriving( Show, Eq )
Point { x :: Double, y :: Double } deriving( Show, Eq )

我想要执行以下操作的函数perpendicular

perpendicular (Line m b) (Point x y) = 
        Line m2 b2 where
                m2 = (-1/m)
                b2 = y - m2*x

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

perpendicular (Line m b) = 
        Line m2 where
                m2 = (-1/m)

如果只给了一条线。

这里的问题是我得到了

  

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

2 个答案:

答案 0 :(得分:11)

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

你的案例是一个很好的例子,说明为什么它在haskell中不起作用;如果您有perpendicular someLine,那么haskell编译器应该如何确定您正在谈论的这些功能中的哪一个?在这种情况下,两者都是有效的,但表达式将根据选择的内容而有不同的类型。

答案 1 :(得分:4)

在第一种情况下,您希望perpendicular的类型为Line -> Point -> Line,而在第二种情况下,您希望其类型为Line -> Double -> Line。这表明我们可以使用类型类来执行此操作,其中我们抽象出第二个参数的类型:

class Perpendicular a where
  perpendicular :: Line -> a -> Line

您的第一个案例将成为Point

的实例
instance Perpendicular Point where
  perpendicular (Line m b) (Point x y) = Line m2 b2
    where m2 = (-1/m)
          b2 = y - m2*x

而第二个成为Double的实例。

instance Perpendicular Double where
  perpendicular (Line m b) = Line m2
    where m2 = (-1/m)