[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