Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Efficient overloading in Haskell

Tags:

haskell

I wonder which of the two strategies below is the most efficient for overloading a function (here the function teX in my example).

  1. Using data and pattern matching:

    data TeX
      = TeXt String
      | TeXmath String
      deriving (Show,Read,Eq)
    teX (TeXt t)    = t
    teX (TeXmath t) = "$$" ++ t ++ "$$"
    
  2. Or using a bit of abstraction:

    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 ++ "$$"
    

Surely the first is easier to use and the second easier to enrich; but I wonder if one will run faster than the other, or if Haskell will implement them in the exact same way.

like image 601
Echologie Avatar asked Apr 27 '13 22:04

Echologie


1 Answers

The first one is more space-efficient. Calling a function defined in a type class is equivalent to invoking a method in an object-oriented language: any functions which are polymorphic on the type TeX t (i.e., has TeX t => in the type signature) will have to carry around an extra, implicit parameter, namely a dictionary storing the particular methods for a given instance of TeX.

Now, about faster? I'd imagine that for programs with a small memory footprint, the first way is marginally faster due to less memory allocation and one less indirection to actually calling the teX function. For allocation-heavy programs, the same would hold until the program hits some memory allocation threshold—which the first version would hit later, and would therefore be somewhat faster once the 2nd one hits that point.

like image 101
jpaugh Avatar answered Sep 28 '22 07:09

jpaugh