2016-09-04 18 views
1

この関数を簡潔にするためにポイントフリーにしたいと考えています。私は他の関数にも必要なので、計算するのではなく明示的に長さを渡しています。私はそれを一度計算したいと思います。私は、目標の文字列パラメータを取り除くために管理してきましたが、他の2つと闘っています。この関数を暗黙にする

-- 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

方法の代わりに、分かりやすい部分にそれを壊すことによって、それは単純なことについて? –

+0

確かに、私は提案に開放されています。 – dimid

+0

さて、文字列を別の文字列のスペースと 'cycle'で整列させる関数はどうでしょうか? –

答えて

5

私は真剣に、この特定の機能は、ポイントフリースタイルでそれを書くことによって、より簡単にすることができるということを疑います。例えば、ここで私はpointfree.ioから得たものです:

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

pointfree.ioリファレンスをありがとう。 – dimid

+9

いつものようにpointfreeからのクリスタルクリアな実装。 – amalloy

+0

「フリップフリップ」は取り消すことができますか? – dimid

7

@Reidバートンの提案に続き:

-- 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

'isSpace'をさらにスペース文字に使用できます。 – dfeuer

+0

ありがとう、編集中。 – dimid

+2

ところで、これはあなたが使い始めたコードよりはるかに優れています。私は '!!'にアレルギーがあります。 – dfeuer

関連する問題