[Haskell-cafe] Tips for converting Prolog to typeclasses?

Greg Buchholz haskell at sleepingsquirrel.org
Wed May 31 20:22:33 EDT 2006


    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).
app(C,[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

...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?

Thanks,

Greg Buchholz



More information about the Haskell-Cafe mailing list