[Haskell-cafe] MultiParamClasses question

Stephen Tetley stephen.tetley at gmail.com
Tue May 25 17:46:47 EDT 2010


Hi Eugene


You can store different things in a Map by collecting them with a
simple 'sum' type:

> import qualified Data.Map as Map

> type DateTime = String        -- just String for now..
> type URL      = String
> type UniqueID = String

Here's the sum type:

> data LogData = LastLogin DateTime
>              | LastLogout DateTime
>              | ReferringURL URL
>   deriving (Eq, Show)


> type ExtraInfo = Map.Map UniqueID [LogData]

> addData :: UniqueID -> LogData -> ExtraInfo -> ExtraInfo
> addData uid prop infos = case Map.lookup uid infos of
>     Nothing -> Map.insert uid [prop]    infos
>     Just xs -> Map.insert uid (prop:xs) infos

Note - this stores all the LastLogin's ReferringURLS etc. As the list
is LIFO the first @LastLogin@ in the list will be the latest
one.

If you don't like storing multiples, you could instead recast LogData
as a record rather than sum  type, but you then have to
account for 'missing' data with Maybe's.

> data LogData2 = LogData2
>       { last_login    :: Maybe DateTime
>       , last_logout   :: Maybe DateTime
>       , referring_URL :: Maybe URL
>       }

> emptyLogData2 :: LogData2
> emptyLogData2 = LogData2 Nothing Nothing Nothing

> type ExtraInfo_ALT = Map.Map UniqueID LogData2

> addLastLogin :: UniqueID -> DateTime -> ExtraInfo_ALT -> ExtraInfo_ALT
> addLastLogin uid lasttime infos = case Map.lookup uid infos of
>     Nothing  -> Map.insert uid (emptyLogData2 { last_login = Just lasttime}) infos
>     Just ld2 -> Map.insert uid (ld2 { last_login = Just lasttime}) infos


Make similar functions for last_logout, referring_url.

Best wishes

Stephen


More information about the Haskell-Cafe mailing list