[prev in list] [next in list] [prev in thread] [next in thread]
List: haskell-cafe
Subject: Re: [Fwd: Re: type class VS struct/functor]
From: John Hughes <rjmh () cs ! chalmers ! se>
Date: 2002-01-23 14:01:12
Message-ID: 200201231401.PAA27029 () hotlips ! cs ! chalmers ! se
[Download RAW message or body]
The advantage of functors shows up when you need to have multiple
implementations of a module for a type. For instance, suppose you
want to implement a set, and you write the functors (OCaml below):
...
Now, suppose you want two kinds of sets of string, one of which is
case-sensitive and one of which is not. You can easily do this with
functors like so
module SensitiveCase =
struct
type t = string
let eq s s' = (s = s')
end
module InsensitiveCase =
struct
type t = string
let eq s s' = (String.lowercase s) = (String.lowercase s')
end
module SensitiveSet = Set(SensitiveCase)
module InsensitiveSet = Set(InsensitiveCase)
Each of these Set types takes a string, but the membership test is
different. This is an annoying case in Haskell, because you can make a
String a member of the Eq typeclass in only one way.
Of course, you can always define
newtype CaseInsensitiveString = CaseInsensitive String
whereupon you can define an Eq instance that ignores case. Maybe this isn't
common Haskell style, but it does have many advantages. In particular, the
type-checker now checks that you don't pass a case sensitive string where an
insensitive one is expected, or vice versa, and this should help catch bugs.
I've begun to use this style more, particularly when using QuickCheck. There I
define a new type when I want a different distribution of test data from the
default. I've found it's error-prone to specify which distribution to use
explicitly; much better to let the type-checker figure it out.
John
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic