Haskell中的高效重载

Ech*_*gie 6 haskell

我想知道下面两个策略中哪一个对于重载函数最有效(这里是我的例子中的函数teX).

  1. 使用data和模式匹配:

    data TeX
      = TeXt String
      | TeXmath String
      deriving (Show,Read,Eq)
    teX (TeXt t)    = t
    teX (TeXmath t) = "$$" ++ t ++ "$$"
    
    Run Code Online (Sandbox Code Playgroud)
  2. 或者使用一些抽象:

    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 ++ "$$"
    
    Run Code Online (Sandbox Code Playgroud)

当然第一个更容易使用,第二个更容易充实; 但是我想知道一个人是否会比另一个人跑得更快,或者Haskell会以完全相同的方式实现它们.

jpa*_*ugh 5

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

现在,快一点?我想,对于占用内存较少的程序,第一种方法由于内存分配较少而实际调用该teX函数的间接性较小,因此速度稍快.对于分配繁重的程序,同样会持续到程序达到某个内存分配阈值 - 第一个版本稍后会打到这个阈值,因此一旦第二个程序达到该点就会更快一些.

  • 我认为这个答案过于简单了.由于内联和类型特化,很可能在编译时完全解析`TeX`字典.至于性能,我猜想额外的间接比分配有更大的影响.但我不会依赖我的直觉. (7认同)