views:

83

answers:

1

I'm trying to compile a simple example of generic classes / type patterns (see http://www.haskell.org/ghc/docs/latest/html/users_guide/generic-classes.html) in Haskell but it won't compile. Any ideas about what's wrong with the code would be helpful.

According to the documentation there should be a module Generics with the data types Unit, :*:, and :+: but ghc (6.12.1) complaints about Not in scope: data constructor 'Unit' etc.

It seems like there's a package instant-generics with the data types :*:, :+: and U but when I import that module (instead of Generics) I get the error

Illegal type pattern in the generic bindings
    {myPrint _ = ""}

The complete source code is

import Generics.Instant

class MyPrint a where
  myPrint :: a -> String

  myPrint {| U |} _ = "" 
  myPrint {| a :*: b |} (x :*: y) = "" (show x) ++ ":*:" ++ (show y)
  myPrint {| a :+: b |} _ = ""


data Foo = Foo String

instance MyPrint a => MyPrint a

main = myPrint $ Foo "hi"

and I compile it using

ghc --make Foo.hs -fglasgow-exts -XGenerics -XUndecidableInstances

P.S. The module Generics export no data types, only the functions:

canDoGenerics
mkGenericRhs
mkTyConGenericBinds
validGenericInstanceType
validGenericMethodType
+6  A: 

Ok, I don't know that much about generics, but the symbols you're looking for are in the Data.Generics module, so I did

import Data.Generics

Second, the line

myPrint {| a :*: b |} (x :*: y) = "" (show x) ++ ":*:" ++ (show y)

has two problems: first, the "" is obviously too much. Second, you can't use show as the types used are not necessarily instances of the Show typeclass. So I made this line

myPrint {| a :*: b |} (x :*: y) = (myPrint x) ++ ":*:" ++ (myPrint y)

Finally, with

instance MyPrint a => MyPrint a

you first require that a is an instance of MyPrint and then you ask the compiler to derive a MyPrint instance for a that you required to already exist. This works for me:

instance MyPrint Foo

However, you have to manually provide an instance for String first so that the compiler has a starting point for derivation:

instance MyPrint String where
  myPrint s = s

Hope that helps.

Rüdiger Hanke