Patrick Browne <patrick.bro...@dit.ie> wrote: > Thanks for all the very useful feed back on this thread. > I would like to present my possibly incorrect summarized view: > Class signatures can contain placeholders for constructors. > These place-holder-constructors cannot be used in the class to define > functions (I assume other in-scope constructors can be used). In the > instance a real constructor can be substituted for the > place-holder-constructor. Does this restrict the type of equation > that can be used in a type class? It seems that some equations > respecting the constructor discipline are not allowed.
Your intuition seems to be near the truth, although your terminology is currently wrong. Let's look at an example: class Functor f where fmap :: (a -> b) -> (f a -> f b) The 'f' in the class header is probably what you call a "placeholder for constructors". This is not a placeholder, but a type variable. It represents a type. Incidentally in this case it indeed represents a constructor, namely a /type/ constructor (like Maybe). This is an important distinction, because generally when we talk about "constructors", we mean /value/ constructors (like Just or Nothing): data Maybe a = Just a | Nothing Here Maybe is a type constructor. This is because it's not a type in its own right, but is applied to another type (like Int) to yield an actual type (Maybe Int). The type Maybe is applied to is represented by the type variable 'a' in the code above. To simplify communication we often call Maybe itself also a type, but it's really not. Let's write the Functor instance for Maybe. It is common to use a helper function (a so-called fold function), which allows us to express many operations more easily. It's called 'maybe' for Maybe: maybe :: b -> (a -> b) -> Maybe a -> b maybe n j (Just x) = j x maybe n j Nothing = n instance Functor Maybe where fmap f = maybe Nothing (Just . f) This is the instance for Maybe. The type variable 'f' from the class now becomes a concrete type constructor Maybe. In this instance you have f = Maybe, so the type of 'fmap' for this particular instance becomes: fmap :: (a -> b) -> (Maybe a -> Maybe b) The notable thing here is that this is really not a placeholder/replacement concept, but much more like a function and application concept. There is nothing that stops you from having type variables in an instance: instance Functor (Reader e) where As you can see there is still what you called a "placeholder" in this instance, so the placeholder concept doesn't really make sense here. The declaration can be read as: "For every type 'e' the type 'Reader e' is an instance of the Functor type class." > I appreciate that in Haskell the most equations occur in the > instances, [...] Not at all. When programming Haskell you write lots and lots of equations outside of class instances. Whenever you write "=" you introduce an equation, for example in top-level definitions and in 'let' and 'where' bindings. > [...] but from my earlier post: "I merely wish to identify the > strengths and weakness of *current Haskell type classes* as a pure > *unit of specification*" I think you will be interested in this Stack Overflow answer: <http://stackoverflow.com/a/8123973> Even though the actual question answered is different, it does give a nice overview of the strengths and weaknesses of type classes. Greets, Ertugrul -- Not to be or to be and (not to be or to be and (not to be or to be and (not to be or to be and ... that is the list monad.
signature.asc
Description: PGP signature
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe