Re: [Fwd: Re: type class VS struct/functor]

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
participants (1)
-
John Hughes