2

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

1 Answer 1

7

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.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.