Haskell: спасшийся персонаж от персонажа - PullRequest
2 голосов
/ 24 августа 2010

Я пишу синтаксический анализатор парсек, который читает строки и преобразует экранированные символы в рамках упражнения 3 здесь .

Для этого упражнения я использую эту функцию:

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

Меня не впечатляет использование read для преобразования символа x в escape-символ с именем x.Кто-нибудь может предложить более элегантную функцию типа Char -> Char для этого?

Ответы [ 3 ]

6 голосов
/ 25 августа 2010

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

В конце концов, вы должны где-то определить семантику. Вы можете сделать это в своей программе или использовать GHC.

5 голосов
/ 24 августа 2010

Одним из способов является исчерпывающее описание дел:

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 .

1 голос
/ 24 августа 2010

Я просто использовал сопоставление с образцом для немногих побегов, о которых я заботился - т.е. 't' -> '\t' и т. Д.Решение, предложенное другими читателями, было аналогичным.Не очень общий, но очень простой.

...