我正在寫一個parsec分析器,它讀取字符串並轉換轉義字符,作爲練習3 here的一部分。Haskell:字符轉義的字符
爲了鍛鍊我使用這個功能:
escapedCharFromChar :: Char -> Char
escapedCharFromChar c = read $ concat ["'\\",[c],"'"]
我不是深刻的印象使用read
的字符x
轉換成轉義字符的名稱x
。任何人都可以提出一個更優雅的功能Char -> Char
這樣做嗎?
我正在寫一個parsec分析器,它讀取字符串並轉換轉義字符,作爲練習3 here的一部分。Haskell:字符轉義的字符
爲了鍛鍊我使用這個功能:
escapedCharFromChar :: Char -> Char
escapedCharFromChar c = read $ concat ["'\\",[c],"'"]
我不是深刻的印象使用read
的字符x
轉換成轉義字符的名稱x
。任何人都可以提出一個更優雅的功能Char -> Char
這樣做嗎?
的方法之一是詳盡鋪陳情況:
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 something
(即,c
在escapes
的條目),但是這會散架時假設是無效的:
ghci> charFromEscape 'r' *** Exception: Maybe.fromJust: Nothing
這些例子會在練習中讓你感動,但很明顯你會喜歡更好的錯誤處理。此外,如果您希望查找表很大,您可能需要查看Data.Map。
我剛剛使用了模式匹配方法來處理我關心的幾個逃跑 - 也就是't' -> '\t'
等。其他讀者提出的解決方案是相似的。不是非常通用的,但非常直接。
read
(或者說,Text.Read.Lex.lexCharE
)是你如何讓在GHC's internal table,其定義爲:
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。
這是一個恥辱'lexEscChar'沒有出口,否則這將是一個完美的答案。儘管感謝您的領導。 – dukedave 2010-08-25 17:03:34