Нет смысла логику из кейса выносить далеко. Я написал свой костыль для этого дела - 
Код:
tst
, применяю его для монады Мэйби в трех местах внутри кода:
parseRegExp :: String -> Maybe RegExp
parseRegExp s  = go s nl where
    nl = Just []
    packlist []  = Nothing
    packlist [a] = Just $ a
    packlist  l  = Just $ Str $ reverse l
    tst r
        | r         = Nothing
        | otherwise = Just undefined
    spanclose s = tst (null w) >> Just (init l, drop (length l) s) where
        w = filter ((==(-1)).sum.map f).inits $ s
        l = head w
        f '(' = 1
        f ')' = -1
        f  _  = 0
    go _       Nothing = Nothing
    go []     (Just l) = packlist l
    go (c:cs) (Just l) = case c of
        '(' -> spanclose cs >>= \(sl,sr) -> go sr $ go sl nl >>= Just.(:l)
        '|' -> packlist l >>= \pl -> go cs nl >>= \pr -> Just $ Or pl pr
        '*' -> tst (null l) >> (go cs $ Just $ ZeroOrMore (head l) : (tail l))
        '.' -> go cs $ Just $ BAny : l
        _   -> tst (not $ isAlpha c) >> (go cs $ Just $ Normal c : l)
  -- 21.01.2015, 02:45 --У меня в каждом (почти) кейсе разбора очередного символа может произойти неудача разбора и надо вернуть Nothing - удобно это делать по одному паттерну - только что освоенному мною монаде Мэйби. Но тогда и входящие условия надо переводить в Nothing при неудаче - для этого и костыль tst :) По-моему логика приобретает стройность даже на костыле :)