I posted this to comp.lang.functional a while ago but (apparently) no one
had an opinion which
I cant believe is the case :-)
Chris
I would be interested to know people's views on adding reflection to Haskell
to get Factory-like behaviour.
I was thinking that other modules could "export" values as being reflective
and the compiled code could register these values
at load-time into a list
reflections :: [(FullyQualifiedName,Dynamic)]
and values could be requested from it a la...
lookup :: a -> Name -> Maybe a
Where the initial "a" is needed to make it all typesafe
If we had this we could implement additive code
i.e. rather than
myImageReader :: String -> IO Image
myImageReader name
= case (getExtension name) of
BMP -> Bmp.readBmp name
JMG -> Jpg.readJpg name
_ -> error "unknown type"
we could implement
myImageReader :: String -> IO Image
myImageReader name
= case (Reflect.lookup (bot::String -> IO Image) (makeFnName name) of
Just f -> f name
Nothing -> error "unknown type"
i.e. passing "myfile.bmp" to makeFnName gives
"Bmp.readBmp"
and passing "x.yz" to it gives
"Yz.readYz"
since the list of reflections is built at load time we can extend this
functionality by simply linking extra modules with it
i.e.
main.o can read no file types
main.o + bmp.o can read bitmaps
main.o + bmp.o + jpg.o can read bmps and jpgs
i.e. we do not have to exit case statements and extend types to
add extra functionality
in Bmp.hs say we could have
module Bmp where
import Image
reflect readBmp
readBmp :: String -> IO Image
...
which would get munged to
module Bmp where
import Image
-- This gets appended to the global reflection list at load time --
[("Bmp.readBmp",toDynamic readBmp)]
readBmp :: String -> IO Image
...
All of this means that the meaning of the code is not the following
eval main userAndLibraryDefs
but the following
eval main (userAndLibraryDefs + LoadTimeDefs)
and we still have ref. transparency