A word to the wise

If you only implement the less than operator in a custom Ord instance (on the theory that “I know I only need to implement one operation to get defaults for the others, and less than makes sense, since you can get anything using less than and equals”), the compiler gives zero warnings (even with -Wall) and trying to compare anything will send your program into nasty infinite recursion. It turns out that you have to implement less than or equal to (or the ‘compare’ function), not less than. Says so in the docs for Ord, of course, but… sigh.

In related news, the new ghci debugger is quite helpful. =)

And in unrelated news, I’m finally done with grad school and fellowship applications!!

About these ads
This entry was posted in grad school, haskell and tagged , , . Bookmark the permalink.

4 Responses to A word to the wise

  1. I’ve always thought this was poor. Consider the case for Eq, you could define it so == in terms of /=, and vice versa. The default with no implementation would then give you horrible recursion. Perhaps we need some notation of what you’ve given compared to what you get – comments are not sufficient.

  2. Brent says:

    Neil: Now that I’ve run into this problem (and spent an hour or so tracking it down) I definitely agree with you.

    Hmm… it seems like it wouldn’t be that hard for the compiler to detect circular dependencies among default implementations and give you a warning if the implementation you provide leaves any cycles among the non-overridden defaults. Are there any hidden “gotchas” that I’m not thinking of here?

  3. Brent: No, looks trivial to me! I would actually get the compiler to replace any circular dependencies with error “Method not defined at “, as well as a compile time warning. Raise a GHC bug!

  4. Pseudonym says:

    There’s one more issue to consider:

    Nowhere in the Haskell report does it state that x != y means the same thing as not (x == y). It’s worse with Ord, because:

    nan > nan = False

    but:

    compare nan nan = GT

    One more thing. This is dumb, but it’s not morally wrong:

    class Foo a where
    op1 :: a -> Bool
    op2 :: a -> Bool

    op1 x = True || op2 x
    op2 x = False && op1 x

    instance Foo Int where {}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s