Type patterns in Haskell
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
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.
精彩评论