J'ai écrit un code Haskell qui doit résoudre le problème suivant: nous avons n fichiers: f1, f2, f3 .... fn et j'ai coupé ces fichiers de manière que chaque tranche a 100 lignesComment faire mon code Haskell utiliser Laziness et Garbage collector
f1_1, f1_2, f1_3 .... f1_m
f2_1, f2_2, .... f2_n
...
fn_1, fn_2, .... fn_k
enfin je construis un type de données spécial (Dags) en utilisant des tranches de la manière suivante
f1_1, f2_1, f3_1, .... fn_1 => Dag1
f1_2, f2_2, f3_2, ..... fn_2 => Dag2
....
f1_k, f2_k, f3_k, ..... fn_k => Dagk
le code que j'ai écrit début en coupant tous les fichiers, il coupler les éléments de la liste des résultats et construire Dag en utilisant la liste des résultats finaux
il ressemble à ceci
-- # take a filename and cut the file in slices of 100 lines
sliceFile :: FilePath -> [[String]]
-- # take a list of lists and group the i-th elements into list
coupleIthElement :: [[String]] -> [[String]]
-- # take a list of lines and create a DAG
makeDags :: [String] -> Dag
-- # final code look like this
makeDag_ :: [FilePath] -> [Dag]
makeDags files = map makeDags $ coupleIthElement (concat (map sliceFile files))
Le problème est que ce code est non-efficace, car:
dont il a besoin stocker tous les fichiers dans la mémoire sous forme de listes
le garbage collector ne fonctionne pas efficacement puisque toutes les fonctions ont besoin de la liste des résultats de la fonction précédente
Comment puis-je réécrire mon programme pour tirer parti du travail de garbage collector et de Laziness of Haskell?
Si ce n'est pas possible ou plus facile, que puis-je faire pour être plus efficace, même un peu?
merci pour la réponse
modifier
coupleIthElement ["abc", "123", "xyz"]
doit retourner ["a1x","b2y","c3z"]
des causes les 100 lignes sont arbitraires sélectionnées en utilisant un critère particulier sur certains éléments des lignes, mais je jeter cet aspect pour rendre le problème plus facile à comprendre,
une autre édition
data Dag = Dag ([(Int, String)], [((Int, Int), Int)]) deriving Show
test_dag = Dag ([(1, "a"),(2, "b"),(3, "c")],[((1,2),1),((1,3),1)])
test_dag2 = Dag ([],[])
la première liste est chaque Vertice définit par le nombre et l'étiquette, la deuxième liste est les bords ((1,2),3)
signifie arête entre Vertice 1 et 2 avec le coût 3
Y a-t-il quelque chose d'important dans les 100 groupes de lignes, ou est-ce arbitraire? –
Votre type "sliceFile" n'a pas de sens: il doit sûrement retourner "IO [[String]]" –
ByteStrings fonctionnerait-il à la place de Strings? Ce serait plus efficace. –