Code Review Stack Exchange is a question and answer site for peer programmer code reviews. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Write a function Int -> Char -> Char -> [String] that will create the appropriate pattern.

For example: mapM_ putStrLn (pattern 48 '.' '+')

................................................
.+..+..+..+..+..+..+..+..+..+..+..+..+..+..+..+.
+.++.++.++.++.++.++.++.++.++.++.++.++.++.++.++.+
................................................

This idea is inspired by Write nested `for` loops to produce following output (but more general).

I am pretty satisfied with my code to solve this problem:

pattern :: Int -> Char -> Char -> [String]
pattern len a b = map (take len . cycle) [[a], [a, b, a], [b, a, b], [a]]

main :: IO()
main = mapM_ putStrLn (pattern 48 '.' '+')
share|improve this question
up vote 5 down vote accepted

Seems fine. However, depending on the context and the rest of the program, you can relax pattern's type:

pattern :: Int -> a -> a -> [[a]]

Also, since every putStrLn is basically hPutStrLn stdout, you could first glue all lines together with unlines and then print them with a single action:

main = putStr (unlines (pattern 48 '.' '+'))
share|improve this answer
    
I see your suggestions but fail to understand the reasoning about them... why is a general type better? Why is a single action better? – Caridorc Nov 27 '15 at 16:47
1  
@Caridorc: The most important parts of the answer are its first two words: Your code is fine. There are just some stylistic choices/alternatives you can consider. However, about the single action: putStrLn is basically the same as puts in C. From a performance point of view, you try to avoid many I/O calls (I/O, not IO) although this isn't really measurable in this small program. – Zeta Nov 27 '15 at 16:58
    
cool performance trick :) What about the general type? – Caridorc Nov 27 '15 at 17:00
1  
@Caridorc: You cannot use pattern 48 1 2 in your original program ^^. The consensus in Haskell is: if you can make a function more general (without loosing something), make it more general. For example, you could define head :: [Int] -> Maybe Int. But head :: [a] -> Maybe a is a lot more useful. – Zeta Nov 27 '15 at 17:01
    
Yeah, I meant it to be a text pattern, but it is always nice to know when things could be more general. – Caridorc Nov 27 '15 at 17:02

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.