Avoiding "No explicit method ..." warnings

Dean Herington heringto@cs.unc.edu
Tue, 21 Jan 2003 09:16:02 -0500

George Russell wrote:

> This isn't a bug, just a suggestion.  It's not even a very important
> suggestion, but one that might be worth implementing if it's easy and you can
> find the the time.  Or perhaps I am just doing things the wrong way?
> The point is that I sometimes have something like the following situation
> class ComplicatedClass x where
>    simpleTitleFn :: x -> String
>    muchMoreComplicatedTitleFn :: extra arguments -> x -> IO (WithError (Source blah blah blah String)
>    muchMoreComplicatedTitleFn _ x = [ ... some expression involving simpleTitleFn ...]
> The idea is that only muchMoreComplicatedTitleFn must always work; however instances may
> choose to implement it directly, or implement the much simpler function simpleTitleFn
> (if that does all they want).
> At the moment the situation is that someone who defines just "muchMoreComplicatedTitleFn"
> will get an unnecessary warning message from the compiler about "No explicit method or
> default method for simpleTitleFn".  I suggest instead introducing a new class of
> optional method (for example, via a pragma {-# OPTIONAL_METHOD simpleTitleFn #-}) which
> compiles exactly as normal except that (1) no warning is given for instances which don't
> define it; (2) a warning is given whenever anyone outside the class declaration *uses*
> simpleTitleFn.

This seems to be a lot of mechanism for questionable benefit.  A simpler and cleaner approach, IMHO, is
the following:

class ComplicatedClass x where
   complicatedTitleFn :: extra arguments -> x -> IO (WithError (Source blah blah blah String)

makeComplicatedTitleFn :: (x -> String) -> extra arguments -> x -> IO (WithError (Source blah blah blah
makeComplicatedTitleFn simpleTitleFn = [ ... some expression involving simpleTitleFn ...]

Each instance either defines complicatedTitleFn directly, or uses makeComplicatedTitleFn with a simple
title function:

instance ComplicatedClass Foo where
   complicatedTitleFn = makeComplicatedTitleFn simpleFooTitleFn

simpleFooTitleFn = ...