Re: [Haskell-cafe] introspection | meta data

Can you name these fields? If so, haskell has (sorta clumsy) named records, and you can select and update fields by name, and you can replace 'setSFField 3 sf x' with 'sf {somefield=x}'
I did think of this, but unfortunatly my algorithm cant use names (without hard coding all possible combinations )
So what is the general haskell approach to this type of introspection/meta data problem... ?
A C array of pointers maps closest to a MutableArray, which is mostly a list with different performance. Unless you're casting pointers, in which case Dynamic types or the Generic stuff is maybe what you want. Or a redesign ;)
I looked at haskell arrays, but since I cant point to an element in my tuple it wont work out. The ANSI C use of arrays is a really simple (but nasty) way to provide a means for me to loop over a fixed struct record. The Generic library looks super, only had time to browse some slides thus far, but will defiantly try understand that. As for a redesign and
Others have given good answers for this, but I suspect you may have chosen the wrong data structure...
I would be keen on any ideas you have on how to design this in haskell. Learning to think in haskell is after all the goal :-) The example below is trivial and real world, both reasons why I chose to use it. Any comments welcome, none expected :-) Thanks, -- I idea is to perform a search over a number fields in a hierachical fashion where each field can have a wild card. The real world example is printer selection. In a multi-national company all users tend to be on one (or a few) central servers, but require there printouts to come to them locally whereever they are. Users typically range in 1000s and so "by user" defintions are out. Simplified Search fields: Environemnt, Users, Report, Version, Host Printer ---------------------------------------------------------- ---------- The "most" speicific field is host on the right with it becomming more general moving to towards the left. Setup data could choose to override all of report "RPT1" version "Ver1" to Printer "Bobs Printer" *ALL, *ALL, "RPT1", "Ver1", "*ALL", "Bobs Printer" but Simon may be an exception, then a record could be added like so: *ALL, "SIMON", "RPT1", "Ver1", *ALL, "Simons Printer" This record would be found first for simon, but former found found for everyone else. A search starts from fully specific data i.e no wild cards. The basic algortihm I worked out is: 1. Search setup data 2. If no record found 2a: Set current field to most specific field (host in this case) 2b: Toggle current field ( if Wildcard then make it value, if value make it wildcard ) 2c: if current field is *ALL goto 1 above (we stop here to perform a search on the current permutation) 2d: Loop to 2b until no more fields And my haskell working proto type is this: module Main where -- Env User Report Version Host Printer egdata1 = [(("PD7334EU", "*ALL", "*ALL", "*ALL", "*ALL"), "Default Printer"), (("PD7334EU", "USER1", "*ALL", "*ALL", "*ALL"), "User1Printer"), (("PD7334EU", "USER2", "Report1", "Version1", "*ALL"), "User1Report1Printer"), (("PD7334EU", "*ALL", "Report2", "*ALL", "*ALL"), "Report2Printer")] type SearchFilter = (String, String, String, String, String) type Record = (SearchFilter, String) findPrinter :: String -> String -> String -> String -> String -> [Record] -> String findPrinter env user report version host printerdata = findPrinter' sf sf printerdata where sf = (env, user, report, version, host) findPrinter' :: SearchFilter -> SearchFilter -> [Record] -> String findPrinter' ("*ALL", "*ALL", "*ALL", "*ALL", "*ALL") _ _ = "" findPrinter' sf origsf printerdata | printer == "" = findPrinter' (toggle sf origsf 5) origsf printerdata | otherwise = printer where printer = searchPrinter sf printerdata searchPrinter :: SearchFilter -> [Record] -> String searchPrinter _ [] = "" searchPrinter sf ((x,p):xa) | sf == x = p | otherwise = searchPrinter sf xa toggle :: SearchFilter -> SearchFilter -> Int -> SearchFilter toggle sf origsf 0 = sf toggle sf origsf n | newValue == "*ALL" = newSF | otherwise = toggle newSF origsf (n-1) where newValue = toggleField (getSFField n sf) (getSFField n origsf) newSF = setSFField n sf newValue toggleField :: String -> String -> String toggleField "*ALL" x = x toggleField _ _ = "*ALL" getSFField :: Int -> SearchFilter -> String getSFField 1 (x,_,_,_,_) = x getSFField 2 (_,x,_,_,_) = x getSFField 3 (_,_,x,_,_) = x getSFField 4 (_,_,_,x,_) = x getSFField 5 (_,_,_,_,x) = x setSFField :: Int -> SearchFilter -> String -> SearchFilter setSFField 1 (a,b,c,d,e) f = (f,b,c,d,e) setSFField 2 (a,b,c,d,e) f = (a,f,c,d,e) setSFField 3 (a,b,c,d,e) f = (a,b,f,d,e) setSFField 4 (a,b,c,d,e) f = (a,b,c,f,e) setSFField 5 (a,b,c,d,e) f = (a,b,c,d,f) main = putStrLn (findPrinter "PD7334EU" "USER2" "Report2" "Version3" "SomeHost" egdata1) _________________________________________________________________ Add photos to your messages with MSN 8. Get 2 months FREE*. http://join.msn.com/?page=features/featuredemail
participants (1)
-
Crypt Master