[Haskell-cafe] Tips for converting Prolog to typeclasses?
robdockins at fastmail.fm
Wed May 31 20:59:35 EDT 2006
On Wednesday 31 May 2006 08:22 pm, Greg Buchholz wrote:
> Lately, in my quest to get a better understanding of the typeclass
> system, I've been writing my typeclass instance declarations in Prolog
> first, then when I've debugged them, I port them over back over to
> Haskell. The porting process involves a lot trial and error on my part
> trying to decide when to use functional dependencies and which compiler
> extension to enable ( -fallow-undecidable-instances,
> -fallow-overlapping-instances, etc.). Which might be okay, but I still
> can produce things that won't compile, and I don't necessarily know if
> I'm making a fundamental mistake in a program, or if there's something
> trivial that I'm not doing quite right.
> For example, there was a question on haskell-cafe last week about
> creating an "apply" function. My first solution (
> http://www.haskell.org//pipermail/haskell-cafe/2006-May/015905.html )
> was to use type classes and nested tuples for the collection of
> arguments. This works fine. But then I wanted to try to get closer to
> what the original poster wanted, namely to use regular homogenous lists
> to store the arguments. So I thought I could reuse the class definition
> and just provide new instances for a list type, instead of the nested
> tuple type. Here's the class definition...
> > class Apply a b c | a b -> c where
> > apply :: a -> b -> c
> ...So I wrote the following Prolog snippets which seemed like they might
> properly describe the situation I was looking for...
> :- op(1000,xfy,=>). % use => instead of -> for arrow type
> app(A=>B,[A],C) :- app(B,[A],C).
> ...which I translated into the following Haskell instances...
> > instance Apply b [a] c => Apply (a->b) [a] c where
> > apply f  = error "Not enough arguments"
> > apply f (x:xs) = apply (f x) xs
> > instance Apply c [a] c where
> > apply f _ = f
To make this work, you're going to have to convince the compiler to accept
"overlapping instances" and then make sure they don't overlap :) In the
second instance, what you really want to say is "instance c [a] c, only where
c is not an application of (->)". As I recall, there is a way to express
such type equality/unequality using typeclasses, but I don't remember how to
do it offhand.
A quick google turns up this page, which appears to address most of the
questions at hand:
> ...and here's a test program...
> > g :: Int -> Int -> Int -> Int -> Int
> > g w x y z = w*x + y*z
> > main = do print $ apply g [1..]
> ...but I haven't been able to get GHC to accept this yet. So I'm
> wondering if there's an easy route to learning this stuff. Some sort of
> comprehensive tutorial out there which I should be reading that
> describes what should be possible with Haskell's typeclasses plus GHC
> extenstions, and when and where to enable these extentions. (Bonus
> points awarded if it explains things in terms of Prolog). Or is this
> just one of those things that requires reading lots of papers on each
> extentsion and possibly the source code of the implementation?
> Greg Buchholz
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
Talk softly and drive a Sherman tank.
Laugh hard, it's a long way to the bank.
More information about the Haskell-Cafe