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

duk*_*ave 2 haskell escaping char

我正在写一个秒差距解析器读取串并转换转义字符,锻炼3的一部分在这里.

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

escapedCharFromChar :: Char -> Char
escapedCharFromChar c = read $ concat ["'\\",[c],"'"]
Run Code Online (Sandbox Code Playgroud)

使用read将字符x转换为带有名称的转义字符时,我不会留下深刻的印象x.任何人都可以建议更优雅的类型功能Char -> Char来做到这一点?

jro*_*way 6

read(或者更确切地说,Text.Read.Lex.lexCharE)是你如何得到GHC的内部表,其定义如下:

 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
Run Code Online (Sandbox Code Playgroud)

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


Gre*_*con 5

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

charFromEscape :: Char -> Char
charFromEscape 'n' = '\n'
charFromEscape 't' = '\t'
--- ... --- Help!
Run Code Online (Sandbox Code Playgroud)

你也可以使用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
Run Code Online (Sandbox Code Playgroud)

fromJust可能看起来很奇怪.类型lookup

lookup :: (Eq a) => a -> [(a, b)] -> Maybe b
Run Code Online (Sandbox Code Playgroud)

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

data Maybe a = Just a | Nothing
Run Code Online (Sandbox Code Playgroud)

有了fromJust它假定你有Just something(,c在一个条目escapes),但是这会散架时假设是无效的:

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

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