In this question, der Autor bringt eine interessante Programmierfrage: gegeben zwei String, finden Sie mögliche 'verschachtelte' Permutationen von denen, die Reihenfolge der ursprünglichen Strings bewahrt.Interleaving zwei Strings, Erhalt der Reihenfolge: funktionalen Stil
generali ich das Problem zu n
Strings anstelle von 2 im Falle des OP, und kam mit:
-- charCandidate is a function that finds possible character from given strings.
-- input : list of strings
-- output : a list of tuple, whose first value holds a character
-- and second value holds the rest of strings with that character removed
-- i.e ["ab", "cd"] -> [('a', ["b", "cd"])] ..
charCandidate xs = charCandidate' xs []
charCandidate' :: [String] -> [String] -> [(Char, [String])]
charCandidate' [] _ = []
charCandidate' ([]:xs) prev =
charCandidate' xs prev
charCandidate' ([email protected](c:rest):xs) prev =
(c, prev ++ [rest] ++ xs) : charCandidate' xs (x:prev)
interleavings :: [String] -> [String]
interleavings xs = interleavings' xs []
-- interleavings is a function that repeatedly applies 'charCandidate' function, to consume
-- the tuple and build permutations.
-- stops looping if there is no more tuple from charCandidate.
interleavings' :: [String] -> String -> [String]
interleavings' xs prev =
let candidates = charCandidate xs
in case candidates of
[] -> [prev]
_ -> concat . map (\(char, ys) -> interleavings' ys (prev ++ [char])) $ candidates
-- test case
input :: [String]
input = ["ab", "cd"]
-- interleavings input == ["abcd","acbd","acdb","cabd","cadb","cdab"]
es funktioniert, aber ich bin ganz mit dem Code betroffen:
- ist es hässlich. kein Punkt-frei!
- explizite Rekursion und zusätzliches Funktionsargument
prev
Staaten zu bewahren - Tupeln als Zwischenform
Wie kann ich das obige Programm neu zu schreiben, um mehr „haskellic“, prägnant, lesbar und anschmiegsamer zu „functional mit Programmierung"?
Ich würde zu weit Punkt-freien Art der Verfolgung nicht empfehlen. Es kann lehrreich sein und sogar Spaß machen, aber wenn man es über einen bestimmten Punkt hinaus nimmt, kann eine punktefreie Programmierung die Dinge weniger lesbar machen, nicht mehr ... – comingstorm
Vermeiden Sie auch Dinge wie '(:) (...) $. .. 'zugunsten von' (...): (...) '. Im obigen Fall brauchst du nicht einmal den zweiten Satz von Parens ... – comingstorm
Ich habe es nicht getestet, aber ich vermute, du wolltest 'charCandidate' schreiben, wo immer du' getCandidate' hast und schreiben willst charCandidate'' überall dort, wo Sie 'charCandidate' in den fünf Zeilen nach der Typdeklaration für' charCandidate' haben. –