On Jun 7, 2011, at 12:43 PM, MigMit wrote:


One particularly trivial example that comes to mind is:

  newtype Mu f = Mu (f (Mu f))

  instance Show (f (Mu f)) => Show (Mu f) where
      show (Mu x) = "Mu (" ++ show x ++ ")"
      -- Or however you'd like to show it

Ehm, that does look like poor design.

Sure you don't mean "Mu f can be printed if and only if f (Mu f) can be printed". What you probably mean is "if f transforms printable things to printable things, then Mu f is a printable thing". And you CAN express just that:


Actually, I would argue that the former _is_ what is meant. It's a weaker condition than the latter and it is the necessary and sufficient condition to define the instance - one of the steps involved in formatting a value of type "Mu f" is to format a value of type "f (Mu f)". It doesn't actually matter whether "forall x. Show x => Show (f x)" holds in general.

type ShowD a = forall p. (forall x. Show x => p x) -> p a

showD :: Show a => ShowD a
showD px = px

class ShowF f where showF :: Show a => ShowD (f a)

instance Show a => Show (F a) where... -- here goes your "f"

instance ShowF F where showF = showD -- and that is the only line of boilerplate

instance ShowF f => Show (Mu f) where
show (Mu fm) = "Mu (" ++ runShowHelper (showF (ShowHelper show)) fm ++ ")"

newtype ShowHelper x = ShowHelper {runShowHelper :: x -> String}

Sorry for possible bugs — I don't have ghc anywhere near me at the moment, but the idea is clear, I guess.


I don't really see how this is preferable when the compiler can solve the equation automatically. All that is needed is to tell it to try. If portability is a concern then I could see going through the gymnastics (and also eliminating the use of higher-rank types), but that's the only case in which I would consider it the preferred option.

-- James
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to