
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). 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
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: http://okmij.org/ftp/Haskell/types.html
...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
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Rob Dockins Talk softly and drive a Sherman tank. Laugh hard, it's a long way to the bank. -- TMBG