2016-09-04 3 views
1

Ich möchte diese Funktion point-free machen, um es zu vereinfachen. Ich gebe die Länge explizit weiter, anstatt sie zu berechnen, da ich sie auch für andere Funktionen benötige, und ich möchte sie nur einmal berechnen. Ich habe es geschafft, den Ziel-String-Parameter loszuwerden, aber mit den anderen beiden zu kämpfen.Machen Sie diese Funktion tacit

-- Cycle with respect to whitespace (currently only spaces). 
-- Given a source string and its length, and a longer target string 
-- (which may contain spaces) match the source to target such that: 
-- 1. both will have the same length 
-- 2. spaces in the target string will remain spaces 
-- 3. chars from the source string will be cycled 
-- 
-- Example: 
-- src: "ALLY", len: 4 
-- target: "MEET AT DAWN" 
-- Result: "ALLY AL LYAL"     
cycleWS :: String -> Int -> String -> String 
cycleWS str len = fst . (foldr (\x (s, n) -> if x == ' ' then (s ++ " ", n) else (s ++ [str !! (n `mod` len)], n + 1)) ("", 0)) 
+6

Wie wäre es macht es einfacher, indem sie in leicht zu verstehende Stücke zu brechen, statt? –

+0

Sicher, ich bin offen für Vorschläge. – dimid

+0

Nun, wie wäre es mit einer Funktion, um eine Zeichenkette mit den Leerzeichen in einer anderen Zeichenkette anzuordnen, plus 'cycle'. –

Antwort

5

Ich bezweifle es ernsthaft, dass diese spezielle Funktion einfacher gemacht werden kann, indem es in einem Punkt-freien Stil zu schreiben. Zum Beispiel ist hier, was ich von pointfree.io bekam:

cycleWS = ((fst .) .) . flip flip (([]), 0) . (foldr .) . flip flip snd . ((flip . (ap .)) .) . flip flip fst . ((flip . ((.) .) . flip (ap . (ap .) . (. ((,) . (++ " "))) . (.) . if' . (' ' ==))) .) . flip flip (1 +) . ((flip . (liftM2 (,) .) . flip ((.) . (++))) .) . flip flip ([]) . ((flip . ((:) .)) .) . (. flip mod) . (.) . (!!) 
+0

Danke für die pointfree.io-Referenz. – dimid

+9

Kristallklare Implementierungen von pointfree wie immer. – amalloy

+0

Ich frage mich, ob "Flip Flip" beseitigt werden kann, da sie ausgleichen? – dimid

7

Nach @Reid Barton Vorschlag:

-- Cycle with respect to whitespace (currently only spaces). 
-- Given a source string and its length, and a longer target string 
-- (which may contain spaces) match the source to target such that: 
-- 1. both will have the same length 
-- 2. spaces in the target string will remain spaces 
-- 3. chars from the source string will be cycled 
-- 
-- Example: 
-- src: "ALLY", len: 4 
-- target: "MEET AT DAWN" 
-- Result: "ALLY AL LYAL"     
cycleWS :: String -> String -> String 
cycleWS = align . cycle 

-- Align with respect to spaces. 
-- Given two strings, source and target, align the source to target such that: 
-- 1. both will have the same length 
-- 2. spaces in the target string will remain spaces 
-- Assume the source string is long enough 
align :: String -> String -> String 
align [] _ = [] 
align _ [] = [] 
align (x:xs) (y:ys) = if isSpace y then y : align (x:xs) ys else x : align xs ys 
+1

Sie können 'isSpace' für mehr Leerzeichen verwenden. – dfeuer

+0

Danke, bearbeitet. – dimid

+2

Das ist übrigens dem Code, mit dem Sie angefangen haben, weit überlegen. Ich bin allergisch gegen '!!'. – dfeuer

Verwandte Themen