This code will print an arrow of asterisks, like:


raisingAsterisks, decreasingAsterisks, arrow :: Int -> [String]
raisingAsterisks n = take n $ iterate ('*' :) "*"
decreasingAsterisks = reverse . raisingAsterisks
arrow n = raisingAsterisks n ++ (tail (decreasingAsterisks n))

main :: IO()
main = mapM_ putStrLn $ arrow 4
  • \$\begingroup\$ Related: A Java version of the same thing. Maybe some inspiration? (I don't speak Haskell much) \$\endgroup\$ – Simon Forsberg Sep 13 '15 at 19:26
  • \$\begingroup\$ @SimonForsberg yes, I just write a program in Haskell to get the same output \$\endgroup\$ – Caridorc Sep 13 '15 at 19:27

The way you're actually generating the list of Strings seems fine, but the formatting, at least in my opinion, can be improved: since raisingAsterisks and decreasingAsterisks are both relatively small "helper" functions for arrow, I would suggest putting them inside a where clause to make things a little easier to read.

arrow :: Int -> [String]
arrow n = increasing ++ tail decreasing
    where increasing = take n $ iterate ('*' :) "*"
          decreasing = reverse increasing

In this context, the variable names could be shortened, due to the fact that it's easy to understand what's happening. Note that the n variable no longer needs to be passed, so increasing and decreasing actually are no longer even functions!

I hope you agree that changing your code just a little greatly improves readability.

  • 1
    \$\begingroup\$ I like this simplification. The best first posts are answers, welcome to CodeReview :D \$\endgroup\$ – Caridorc Sep 13 '15 at 20:52
  • \$\begingroup\$ Also, the increasing list is now generated only once. (And it will be kept complete in memory anyway because of reverse.) \$\endgroup\$ – Carsten S Sep 13 '15 at 23:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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