我想知道以下两种策略中哪种策略最有效地重载了函数(在我的示例中为teX)。

  • 使用data和模式匹配:
    data TeX
      = TeXt String
      | TeXmath String
      deriving (Show,Read,Eq)
    teX (TeXt t)    = t
    teX (TeXmath t) = "$$" ++ t ++ "$$"
    
  • 或使用一些抽象:
    class TeX t where
      teX :: t -> String
    
    newtype TeXt = TeXt String
      deriving (Show,Read,Eq)
    instance TeX TeXt where
      teX (TeXt t) = t
    
    newtype TeXmath = TeXmath String
      deriving (Show,Read,Eq)
    instance TeX TeXmath where
      teX (TeXmath t) = "$$" ++ t ++ "$$"
    

  • 当然,第一个更易于使用,第二个更易于丰富;但是我想知道一个运行速度是否会比另一个运行速度快,或者Haskell是否会以完全相同的方式实现它们。

    最佳答案

    第一个是更节省空间的。调用在类型类中定义的函数等效于以面向对象的语言调用方法:在TeX t类型上多态的任何函数(即,在类型签名中具有TeX t =>的函数)都必须带有一个额外的隐式参数,即存储给定TeX实例的特定方法的字典。

    现在,快一点了吗?我以为对于内存占用较小的程序,第一种方法会由于内存分配减少和间接调用teX函数的间接性而稍快一些。对于需要大量分配的程序,直到程序达到某个内存分配阈值之前,该程序将一直保持不变-第一个版本将在以后达到该阈值,因此,一旦第二个版本达到该阈值,它将更快一些。

    10-08 12:48