
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.