[Haskell-cafe] Web application design advice

Sævar Berg s.b.saevarsson at gmail.com
Mon Jul 25 15:18:40 CEST 2011


Hello, Café.

I am really not fond of web development, but being able to do it in my
favorite language is interesting, so I've been spending some time taking a
look at happstack.

I decided to start a concrete project so that I could work towards some goal
in my learning process, and I have decided on writing an inventory
management system for this small computer workshop I work in as a volunteer.
We probably have several metric tonnes of various computer equipment;
interntal hardware(RAM, hard drives, graphics card, processors and so on) to
peripherals and even non-computer related stuff, and it would be good to be
able to catalog it and know what exactly we have and so on.

Anyway, my question is about the design itself. My original idea for the
database was to create a data type, something like

data Hardware =
    Ram
    { ramType :: RamType
    , ramSize :: Int
    ...
    }

data RamType = SDRAM | DDR | DDR2 | DDR3 ..

The obvious advantage to this is type safety and thus having an ORM
database, so to speak(Please forgive me if my web dev lingo is off here,
this is *really *not my forté).
However, a big disadvantage is that we might want to add new 'type' of
hardware to the database and this would require me to stop the server,
modify the haskell code to add a new type constructor and so on.
On top of that, since a graphics card has different attributes than RAM, I
will need to dynamically generate the forms required to add new hardware to
the database or to search for hardware in the database.

Due to this, I had another idea. I would create a state type that would
merely represent groups of items using a map of some kind, where the group
name would be a string. Maybe something like this:

data HardwareGroup =
    HardwareGroup
    { groupName :: String
    -- Valid key values for the map
    , groupValues :: [String]
    , groupItems :: [Data.Map String String]
    }

Which means I can create a new group like this:

type Hardware = [HardwareGroups]

hardwareDatabase :: Hardware
hardwareDatabase = []

newGroup = HardwareGroup "RAM" ["ramSize", "ramSpeed", "ramType", "ramName"]
Data.Map.empty

-- Nothing if some value in map isn't a valid part of
addToGroup :: HardwareGroup -> Data.Map String String -> Maybe HardwareGroup
addToGroup (HardwareGroup name values items) m =
    case (any (flip notElem values) $ keys m) of
      True -> return Nothing
      _     -> return $ HardwareGroup name values (m : items)

addToGroup newGroup (fromList [("ramSize", "512"), ("ramSpeed", "400 Mhz"),
("ramType", "DDR"), ("ramName", "Kingston")])

The code may not be correct. I wrote it in this email and didn't test it,
but I assume you guys get what I'm going for here.
This will enable me to dynamically generate forms in an easy manner and add
to / search in the database, without having to think about some types being
strings and some types being ints or something entirely different.

The reason I've come here asking this question and not some web design
mailing list is because I'm writing this in Haskell, and I was wondering if
you guys could see some disadvantages to either design that I may not have
foreseen, or even come up with other suggestions.

I would just really appreciate any hints, tips, pros or cons to either
design. Am I losing something big by sacrificing type safety? Or is the
first idea unwieldy enough to justify the sacrifices?

Thanks a lot in advance guys.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20110725/4be141fd/attachment.htm>


More information about the Haskell-Cafe mailing list