[Haskell-beginners] Using Maybe monad with Zipper
Hugo Ferreira
hmf at inescporto.pt
Mon Nov 14 12:02:49 CET 2011
Hello,
I picked up code that originally had the following function:
leftCursor :: Z.Zipper a -> Maybe a
leftCursor z = if Z.beginp z then
Nothing
else
Z.safeCursor $ Z.left z
However now I need a functions that returns all three elements
to the left of the zipper. I then considered using composition
and came up with the following:
left :: Maybe (Z.Zipper a) -> Maybe (Z.Zipper a)
left (Just z) = if Z.beginp z
then
Nothing
else
Just $ Z.left z
left Nothing = Nothing
cursor :: Maybe (Z.Zipper a) -> Maybe a
cursor (Just z) = Z.safeCursor z
cursor Nothing = Nothing
which I then used as follows:
instPrev1Of3TagRule :: POSTags -> Maybe TransformationRule
instPrev1Of3TagRule z = do
(_, _, prev1) <- leftCursor z
(_, _, prev2) <- (cursor . left . return) z
(_, _, prev3) <- (cursor . left . left . return) z
(_, correct, incorrect) <- Z.safeCursor z
return $ Prev1Of3TagRule (Replacement incorrect correct) prev1
prev2 prev3
But I was not happy with this for two reasons:
1. I was repeating work needlessly. I should pick up the last
zipper and just move the cursor again once for the next
character.
2. I was not taking advantage of the Maybe Monad
So I finally changed the above to:
left :: Maybe (Z.Zipper a) -> Maybe (Z.Zipper a, a)
left (Just z) = if Z.beginp z
then
Nothing
else
Just $ (Z.left z, Z.cursor z)
left Nothing = Nothing
instPrev1Of3TagRule :: POSTags -> Maybe TransformationRule
instPrev1Of3TagRule z = do
(z1,(_, _, prev1)) <- (left . return) z
(z2, (_, _, prev2)) <- (left . return) z1
(_z3, (_, _, prev3)) <- (left . return) z2
(_, correct, incorrect) <- Z.safeCursor z
return $ Prev1Of3TagRule (Replacement incorrect correct) prev1
prev2 prev3
So my question is, is this correct? Can the above code be made
simpler/cleaner? Somehow the double use of Maybe seems wrong.
TIA,
Hugo F.
More information about the Beginners
mailing list