I want to conver bibtex entry into my own custom data type, which looks something like:
date MyEntry = MyEntry {
ident :: String,
author :: [String],
address :: String
}
But fields like author and address are stored in the bibtex’s fields array:
data T =
Cons {
entryType :: String,
identifier :: String,
fields :: [(String, String)]
}
deriving (Show)
An example of the above would be something like:
Cons {entryType = “Book”, identifier = “Arrighi”, fields = [(“author”,
“Arrighi, Gino”),(“title”,”Leonardo Fibonacci : La Pratica di
Geometria. (Volgar izzata da Cristofano di Gherardo di Dino, cittadino
pisano. Dal Codice 2186 dell a Biblioteca Riccardiana di Firenze.) / A
cura e con introduzione di Gino Arrigh
i.”),(“address”,”Pisa”),(“publisher”,”Domus
Galilaeana”),(“date”,”1966″),(“note” ,”(Testimonianze di storia della
scienza, 3)”),(“language”,”italian”),(“pagetota
l”,”234″),(“hyphenation”,”italian”)]}
How can I pattern match on it to convert it to my data type?
I got stuck immediately (this doesn’t work):
toEntry Cons { @entryType, @ident, @fields } = toEntry' entryType' ident fields'
toEntry' entryType ident fs = MyEntry { ident, entryType, ???????? }
You can pattern match on records as described by @ehird, but I think you have also asked about how to convert “fields” list into your “author” and “address” fields.
You can use standard Prelude function “lookup” for this. It works as follows:
It may return “Nothing” if key is not found or “Just value” otherwise.
So you may convert between these two data types with something like this:
Here, you convert Nothing into an empty string, which is generally not a good idea. Therefore, you may need to change type of address from “String” to “Maybe String” to consider the fact that address may be missing from the original fields.
Moreover, you may have experience problems with multiple authors, since “lookup” returns the first matching key’s value and that’s all. To handle multiple “author” fields, you may either write your custom lookup function or convert fields list into a Data.Map, concatenating the values of the same key. Here is how (I have changed address type to list, in order to allow multiple addresses as well):