Using field selectors in a type constructor
Graham Klyne
gk at ninebynine.org
Wed Oct 15 11:45:07 EDT 2003
At 18:38 14/10/03 -0700, Brandon Michael Moore wrote:
>On Mon, 13 Oct 2003, Graham Klyne wrote:
>
> > 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.
Almost! Using 'this' to label the value being defined, I had to add an "in
this" at the end, thus:
[[
joinVarBindings :: (Eq a) => VarBinding a b -> VarBinding a b -> VarBinding a b
joinVarBindings vb1 vb2
| vbNull vb1 = vb2
| vbNull vb2 = vb1
| otherwise = let
this = VarBinding
{ vbMap = headOrNothing . filter isJust . flist [ vbMap vb1,
vbMap vb2 ]
, vbEnum = map (\v -> (v,fromJust (vbMap this v))) $
boundVars vb1 `union` boundVars vb2
, vbNull = False
}
in this
]]
(Getting the layout just right here proved to be a minor challenge)
I hadn't thought of using 'let' in this way, and this led me to wondering
if a form of do might be used...
Out of curiosity, I also tried this:
[[
joinVarBindings :: (Eq a) => VarBinding a b -> VarBinding a b -> VarBinding a b
joinVarBindings vb1 vb2
| vbNull vb1 = vb2
| vbNull vb2 = vb1
| otherwise = do
{ let this = VarBinding
{ vbMap = headOrNothing . filter isJust . flist [ vbMap
vb1, vbMap vb2 ]
, vbEnum = map (\v -> (v,fromJust (vbMap this v))) $
boundVars vb1 `union` boundVars vb2
, vbNull = False
}
; this
}
]]
which according to the Haskell report (p29) should translate to just the
previous example, but Hugs reports a "cannot justify constraints" error ...
it seems to want VarBindings to be a Monad, even though the translation to
a non-do form can be achieved without invoking any monadic operator. Is
this a bug?
Thanks!
#g
------------
Graham Klyne
For email:
http://www.ninebynine.org/#Contact
More information about the Haskell-Cafe
mailing list