[Haskell-cafe] Type classes vr.s functions

wren ng thornton wren at freegeek.org
Tue Dec 23 20:53:17 EST 2008


Brian Hurt wrote:
> 
> So, style question for people, if I can.  I have a certain problem-
> basically, I have a bunch of functions which need a special function,
> of type a -> Foo say.  And a bunch of other functions which can define
> that function on some type of interest, and then what to call the first
> batch of functions.  I can do this either by defining a type class,
> something like:
> class Fooable a where
>     toFoo :: a -> Foo
> or I can simply have all the functions which need a toFoo take an extra
> agrument.  Performance really isn't that important here, so it's really
> a matter of style- which approach would people prefer in this case?

For issues of style, I would say to use type-classes. However, this 
isn't strictly a question of style. As Luke Palmer mentions there are 
differences of power between the two.

In particular, imagine that you have two different and valid ways to 
convert the same type into Foo; which do you choose? With the 
continuation/combinator/argument approach this is a non-issue since you 
can just pass in the one you need. With type-classes it's tricky since 
they're the same type, which leads to hacks with newtype wrappers or 
phantom types.

If there is guaranteed to be only one valid transformation from any 
given type into Foo, then type-classes make your intentions clear and 
they never run into this issue. If more than one valid transformation 
could exist for some type, then the extra argument is cleaner.

Note that when I say "any given type" I mean the domain of values along 
with its semantic connotations. For instance, there's a straightforward 
way of 'converting' Double into an instance of Num. However, if we 
semantically interpret the values of Double as if they were in the 
log-domain, then there is a different way to convert it into Num[1]. But 
really, these are different types because they have different semantics 
even if they have the "same" values. Though much abused, newtype 
declarations are intended to capture exactly this distinction between 
values and semantics, and they make it straightforward for the Haskell 
type-checker to see that they are indeed different types.

[1] http://hackage.haskell.org/cgi-bin/hackage-scripts/package/logfloat

-- 
Live well,
~wren


More information about the Haskell-Cafe mailing list