StringのParse

Haskellのこれをやっているのだが、

parseString :: Parser LispVal
parseString = do char '"'
                 x <- many (noneOf "\"")
                 char '"'
                 return $ String x 

これを改良してエスケープ文字を考慮しよう!というexcersizeで

parseString :: Parser LispVal
parseString = do char '"'
                 x <- many (liftM (\x->[x]) (noneOf "\\\"") <|> (char '\\' >> liftM (\x->('\\':[x])) anyChar))
                 char '"'
                 return $ String $ concat x 

こうするのは何かすごい頭が悪いような気がする。
しかし他に良い手が思いつかない。
tryはまだ説明に出てないから多分使わなくても出来るんだろう。