On Sun, 25 May 2003 23:28:02 +0200 Alain Cremieux <alcremi@pobox.com> wrote:
Hi,
I want to represent a list of (key, values) in Haskell, where key are predefined strings
So I define a datatype using field labels :
data UR = MkUR { fieldA :: Int, fieldB :: Int, fieldC :: String } deriving (Show)
and, for example, we have
testUR = MkUR {fieldA = 1} testUR' = MkUR {fieldA = 2, fieldB = 3, fieldC = "C"}
Now I want to write a function which transforms my datatype in [(String, String)] where a (key, value) element exists if the field is present, and none if the field does not exist.
attrList :: UR -> [(String, String)] attrList u = al "fieldA" (fieldA u) ++ al "fieldB" (fieldB u) ++ al "fieldC" (fieldC u)
al :: (Show a) => String -> a -> [(String, String)] al fn fv = [(fn, show fv)]
(Wouldn't it make more sense to do attrList u = [al "fieldA" (fieldA u), al ...] with al :: ... -> (String,String)?)
Of course, as written, "attrList testUR'" succeeds and "attrList testUR" fails (Missing field in record construction Main.fieldB) I need to match against undefined, which is impossible.
So reify undefined.
Is there a solution (probably involving irrefutable patterns, ~) ?
You want values that may or may not be there. The standard solution is the Maybe type. Assuming you don't want to print out, "Just \"C\"", you can either make your own type with your own instance of show, or use a showValue function in al. The latter is likely preferable as there are quite a few utility functions for the Maybe type already and it's more familiar. You can define al with type ... -> Maybe (String,String) and attrList would just be catMaybes over a list of them, assuming you want attrList(MkUR (Just 5) Nothing (Just "Hello")) to give you [("fieldA","5"),("fieldC","\"Hello\"")] otherwise al can be ... -> (String, Maybe String) and you'd change show fv to fmap show fv, or just ... -> (String,String) with ("fieldB","undefined"/"Nothing"/""/whatever)