Вам не нужно ничего делать.Когда вы вводите строковый литерал
let s = "Newline: \\n Tab: \\t"
, вы можете проверить, что это то, что вам нужно:
Prelude> putStrLn s
Newline: \n Tab: \t
Prelude> length s
19
Если вы просто спросите ghci для значения s
, вы получитечто-то еще,
Prelude> s
"Newline: \\n Tab: \\t"
, по-видимому, он выполняет некоторое резервное форматирование за вашей спиной, а также отображает кавычки.Если вы позвоните show
или print
, вы получите еще другие ответы:
Prelude> show s
"\"Newline: \\\\n Tab: \\\\t\""
Prelude> print s
"Newline: \\n Tab: \\t"
Это потому, что show
предназначен для сериализации значений, поэтому, когда вы show
строка, вы не 'Чтобы получить оригинал обратно, вместо этого вы получаете сериализованную строку, которую можно проанализировать в исходной строке.Результат show s
фактически отображается как print s
(print
определяется как putStrLn . show
).Когда вы просто show s
в ghci, вы получите еще более странный ответ;здесь ghci форматирует символы, которые сериализованы как show
.
tl; dr - всегда используйте putStrLn
, чтобы увидеть значение строки в ghci.
Редактировать : Я только что понял, что, возможно, вы хотите преобразовать буквальное значение
Newline: \n Tab: \t
в фактические управляющие последовательности.Самый простой способ сделать это, вероятно, заключить его в кавычки и использовать read
:
Prelude> let s' = '"' : s ++ "\""
Prelude> read s' :: String
"Newline: \n Tab: \t"
Prelude> putStrLn (read s')
Newline:
Tab:
Edit 2 : пример использования readLitChar
, это очень близко кОтвет Криса за исключением readLitChar
:
strParser :: ReadP String
strParser = do
str <- many (readS_to_P readLitChar)
eof
return str
Затем вы запускаете его с помощью readP_to_S
, который дает вам список подходящих разборов (не должно быть более одного совпадения, однако может не бытьлюбое совпадение, поэтому вы должны проверить пустой список.)
> putStrLn . fst . head $ readP_to_S strParser s
Newline:
Tab:
>