
On Mon, 13 Oct 2003, Graham Klyne wrote:
I've run across a minor coding niggle on a couple opf accosions when using a type constructor with field selectors. The full code of my test case is below. The value 'test2' evaluates to True.
The function that niggles me is this:
[[ joinVarBindings :: (Eq a) => VarBinding a b -> VarBinding a b -> VarBinding a b joinVarBindings vb1 vb2 | vbNull vb1 = vb2 | vbNull vb2 = vb1 | otherwise = VarBinding { vbMap = mv12 , vbEnum = map (\v -> (v,fromJust (mv12 v))) $ boundVars vb1 `union` boundVars vb2 , vbNull = False } where mv12 = headOrNothing . filter isJust . flist [ vbMap vb1, vbMap vb2 ] ]]
Is it really necessary to define mv12 as a separate "where" clause here?
What I'd really like to do is assign it to field vbMap, and reference that from the definition of vbEnum, but I can't figure out if there's a way to do so. Writing this:
Results in a fairly obvious type error: I'd need to have a way to say that vbMap is applied to the value under construction. Experience with Java would suggest maybe something like this: [[ , vbEnum = map (\v -> (v,fromJust (vbMap this v))) $ ]] but of course Haskell isn't Java.
The natural way to do this is to apply vbMap to the value under construction, Haskell being lazy and all. Of course this requires naming the variable under construction it hardly makes a difference when there is only one subexpression. [[ joinVarBindings :: (Eq a) => VarBinding a b -> VarBinding a b -> VarBinding a b joinVarBindings vb1 vb2 | vbNull vb1 = vb2 | vbNull vb2 = vb1 | otherwise = let vb = VarBinding { vbMap = headOrNothing . filter isJust . flist [ vbMap vb1, vbMap vb2 ] , vbEnum = map (\v -> (v,fromJust (vbMap vb))) $ boundVars vb1 `union` boundVars vb2 , vbNull = False } ]] This should work. Brandon.