É seguro em Haskell salvar uma estrutura de dados em um arquivo usando “show” e recuperá-la usando “read”?

5

Digamos que eu tenha os seguintes tipos:

type EndsTup = (Int,Int)
    -- (0-based index from start or end, Frequency)
type FreqTup = (Char, [EndsTup], [EndsTup])
    -- (Character, Freqs from start, Freqs from end)
type FreqData = [FreqTup]
    -- 1 entry in the list for each letter

O que estou usando para armazenar dados sobre a frequência da posição de um personagem em uma palavra. Se eu quiser salvar isso no arquivo, é seguro (como no garantido não corromper se estiver escrito sem erro) converter a estrutura em uma string usando show, e então ler usando algo como:

readData <- readFile filePath
let reconstructed = read readData :: FreqData

Estou apenas perguntando porque isso parece "fácil demais". É assim que normalmente é feito?

    
por Carcigenicate 16.07.2014 / 20:13
fonte

2 respostas

6

É perfeitamente seguro fazer isso dessa maneira, especialmente porque, como Doval apontou, todas as instâncias de Show e Read que você está usando estão na biblioteca padrão e, portanto, garantidas para cooperar com cada uma delas. outro sem qualquer dificuldade.

No entanto, não é a maneira geralmente recomendada de fazê-lo, simplesmente porque o salvamento em texto legível por humanos (e Haskell- read able) está longe de ser tão eficiente quanto um binário baseado em tags formato. Para isso, você pode usar o binary package , que já inclui instâncias para todos os tipos de dados que você está usando na questão.

Mais ao ponto, porém, usar o pacote binary para serializar e desserializar a partir do disco é ainda mais fácil usando Show e Read ! (Basta usar as funções encodeFile e decodeFile ( OrFail ) de Data.Binary Módulo .) Em geral, você terá que se acostumar com as coisas em Haskell sendo muito mais simples, pelo menos nos casos comuns, então eles normalmente estão em linguagens mais imperativas. :)

    
por 17.07.2014 / 07:31
fonte
1

Eu não tentei, mas todos os sinais apontam para "sim", contanto que você use as instâncias derivadas.

O Prelúdio tem isto a dizer sobre o Show :

Derived instances of Show have the following properties, which are compatible with derived instances of Read:

  • The result of show is a syntactically correct Haskell expression containing only constants, given the fixity declarations in force at the point where the type is declared. It contains only the constructor names defined in the data type, parentheses, and spaces. When labelled constructor fields are used, braces, commas, field names, and equal signs are also used.
  • If the constructor is defined to be an infix operator, then showsPrec will produce infix applications of the constructor.
  • the representation will be enclosed in parentheses if the precedence of the top-level constructor in x is less than d (associativity is ignored). Thus, if d is 0 then the result is never surrounded in parentheses; if d is 11 it is always surrounded in parentheses, unless it is an atomic expression.
  • If the constructor is defined using record syntax, then show will produce the record-syntax form, with the fields given in the same order as the original declaration.

E isso tem a dizer sobre Leia :

Derived instances of Read make the following assumptions, which derived instances of Show obey:

  • If the constructor is defined to be an infix operator, then the derived Read instance will parse only infix applications of the constructor (not the prefix form).
  • Associativity is not used to reduce the occurrence of parentheses, although precedence may be.
  • If the constructor is defined using record syntax, the derived Read will parse only the record-syntax form, and furthermore, the fields must be given in the same order as the original declaration.
  • The derived Read instance allows arbitrary Haskell whitespace between tokens of the input string. Extra parentheses are also allowed.

Ênfase minha.

    
por 16.07.2014 / 20:34
fonte