[Haskell-beginners] Exposing Ratio data constructor in prelude

Brent Yorgey byorgey at seas.upenn.edu
Mon Sep 29 12:28:47 EDT 2008

On Mon, Sep 29, 2008 at 06:16:24PM +0200, Casey Rodarmor wrote:
> Hej hej!
> I was writing some code using Ratio, and even though I know it's
> tucked behind an abstraction barrier, I really wanted access to the
> Ratio data constructor ':%'. I wrote invertRatio like such:
> invertRatio r = denominator r % numerator
> But I really wanted to write it like this:
> invertRatio (n :% d) = d % n
> I understand that exposing ':%' causes problems, since it allows us
> not only to pick apart ratios, but to construct bad ones that would
> normally be caught when constructed with '%'. (Such as '1:%0'.)
> Is there any way to avoid this, while still letting the user benefit
> from the nice pattern matching syntax that exposing the data
> constructor allows?

Well, one way to do it would be to write your own destructor function, like so:

    nd :: Ratio a -> (a,a)
    nd r = (numerator r, denominator r)

Then you could use it with a pattern guard:

    invertRatio r | (n,d) <- nd r = d % n

But that's still a bit more syntactically heavyweight than what you'd
really like.  The real answer to your question is views, as proposed
by Wadler in 1987 [1].  Views allow pattern matching to be abstracted
away from the actual representation of a type.  Unfortunately, GHC
6.8.3 does not include views... but GHC 6.10 will! [2] Using GHC 6.10
with the -XViewPatterns extension, you could rewrite invertRatio like

    invertRatio (nd -> (n,d)) = d % n

Hope that answers your question!


1. http://citeseerx.ist.psu.edu/viewdoc/summary?doi=
2. http://www.haskell.org/ghc/dist/stable/docs/users_guide/syntax-extns.html#view-patterns

> Kram,
> Casey
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://www.haskell.org/mailman/listinfo/beginners

More information about the Beginners mailing list