
Hi Felipe, David! It works!!! :-) What I do not really understand, however, is the difference between eval_begin n k = eval n (if (n< 0) then k else (BeginCont k (n - 1))) and eval_begin n k = if (n< 0) then eval n k else eval n (BeginCont k (n - 1)) Anyway, it works and since I needed to use the "Rank2Types" and "RelaxedPolyRec" extensions I have to read (and hopefully understand ;-) these as well. Maybe they'll shed some light onto this. I just wonder: Are typeclasses such an advanced feature that I'd better use alternatives wherever possible? Yitzchak suggested this in this list a few days ago. But almost every (introductory) text explains them as a basic feature. Thanks a lot to both of you! Thomas On 21.07.2011 05:27, Felipe Almeida Lessa wrote:
On Wed, Jul 20, 2011 at 8:41 PM, Thomas
wrote: eval_begin :: Continuation a => Int -> a -> Int eval_begin n k = eval n (if (n< 0) then k else (BeginCont k (n - 1)))
Although 'eval n' is polymorphic, the if expression needs to have just one type, either 'a' or 'BeginCont a', and they can't be unified. The solution is pretty simple, though, since eval's return type doesn't mention 'a' at all:
eval_begin :: Continuation a => Int -> a -> Int eval_begin n k = if (n< 0) then eval n k else eval n (BeginCont k (n - 1))
Note that 'eval n' is repeated. If you don't to repeat it on your real world code you may give it an explicit name. However you'll need to provide a type signature from GHC 7.0 onwards:
eval_begin :: Continuation a => Int -> a -> Int eval_begin n k = let eval' :: Continuation a => a -> Int eval' = eval n in if (n< 0) then eval' k else eval' (BeginCont k (n - 1))
HTH, =)