[Haskell-beginners] type classes and multiple implementations

Michael Hendricks michael at ndrix.org
Fri Jun 5 12:39:50 EDT 2009


I'm writing a tool for which there will be multiple storage formats.
The user can choose his favorite storage mechanism through a
configuration file.  Possible storage mechanisms might include
in-memory storage or on-disk storage.  To represent this abstraction,
I created a Storage type class and two simple instances:

    class Storage a where
        open :: String -> IO a

    data Disk = Disk
    instance Storage Disk where
        open file = do
            putStrLn $ "opening disk: " ++ file
            return Disk

    data Memory = Memory
    instance Storage Memory where
        open _ = do
            putStrLn "opening memory"
            return Memory


I can load this code into ghci (version 6.10.1, if that
matters) and it behaves as I expected it to:

    *Main> open "foo" :: IO Disk
    opening disk: foo
    *Main> open "foo" :: IO Memory
    opening memory

Eventually a configuration facility will provide a string indicating
which storage mechanism the user prefers.  This will return a string
like "memory" or "disk".  Based on that string, I want to return a
value whose type belongs to the Storage type class.  I thought this
would do the job:

    by_type :: Storage a => String -> String -> IO a
    by_type "disk"   x = open x :: IO Disk
    by_type "memory" x = open x :: IO Memory
    by_type _        t = error $ "no such storage type " ++ t

but I get the following compile errors:

    Couldn't match expected type `Disk' against inferred type `Memory'
      Expected type: IO a
      Inferred type: IO Memory
    In the expression: open x :: IO Memory
    In the definition of `by_type':
        by_type "memory" x = open x :: IO Memory

It seems as though the type variable `a' is binding to Disk which
prevents it from later binding to Memory.  That makes sense but I
don't see a way forward from here.  How can I accomplish multiple
implementations of the same interface?  Are type classes the right
way?

Thank you for any help.

-- 
Michael


More information about the Beginners mailing list