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来做到这一点?
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.
一种方法是详尽地列出案例:
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.