哈斯克尔:角色逃脱的角色

时间:2010-08-24 14:28:29

标签: haskell char escaping

我正在编写一个parsec解析器,它读入字符串并转换转义字符,作为练习3 here的一部分。

对于该练习,我正在使用此功能:

escapedCharFromChar :: Char -> Char
escapedCharFromChar c = read $ concat ["'\\",[c],"'"]

使用read将字符x转换为名为x的转义字符时,我不会感到印象深刻。任何人都可以建议使用类型Char -> Char更优雅的功能吗?

3 个答案:

答案 0 :(得分:6)

read(或更确切地说,Text.Read.Lex.lexCharE)是GHC's internal table的结果,定义为:{/ p>

 lexEscChar =
   do c <- get
      case c of
        'a'  -> return '\a'
        'b'  -> return '\b'
        'f'  -> return '\f'
        'n'  -> return '\n'
        'r'  -> return '\r'
        't'  -> return '\t'
        'v'  -> return '\v'
        '\\' -> return '\\'
        '\"' -> return '\"'
        '\'' -> return '\''
        _    -> pfail

最终,您必须在某处定义语义。您可以在程序中执行此操作,也可以重用GHC。

答案 1 :(得分:5)

一种方法是详尽地列出案例:

charFromEscape :: Char -> Char
charFromEscape 'n' = '\n'
charFromEscape 't' = '\t'
--- ... --- Help!

您也可以使用lookup

-- this import goes at the top of your source file
import Data.Maybe (fromJust)

charFromEscape :: Char -> Char
charFromEscape c = fromJust $ lookup c escapes
  where escapes = [('n', '\n'), ('t', '\t')] -- and so on

fromJust位可能看起来很奇怪。 lookup的类型是

lookup :: (Eq a) => a -> [(a, b)] -> Maybe b

这意味着对于定义了相等性的某种类型的值和查找表,它希望从查找表中提供相应的值 - 但不保证您的密钥存在于表中!这就是Maybe的目的,其定义是

data Maybe a = Just a | Nothing

使用fromJust,假设您Just somethingcescapes中有一个条目),但这会分崩离析当该假设无效时:

ghci> charFromEscape 'r'
*** Exception: Maybe.fromJust: Nothing

这些示例将引导您进行练习,但很明显您希望更好地处理错误。此外,如果您希望查找表很大,您可能需要查看Data.Map

答案 2 :(得分:1)

我只是使用模式匹配来处理我关心的少数逃逸 - 即't' -> '\t'等。其他读者建议的解决方案类似。不是很通用,但很直接。