Search code examples
haskellpointfree

Make this function tacit


I'd like to make this function point-free, in order to simplify it. I'm passing the length explicitly instead of computing it, since I also need it for other functions, and I'd like to compute it just once. I've manged to get rid of the target string parameter, but struggling with the other two.

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

Solution

  • I seriously doubt it that this particular function can be made more simple by writing it in a point-free style. For example, here's what I got from 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) . (.) . (!!)