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– Simon Forsberg2015年09月13日 19:26:27 +00:00Commented Sep 13, 2015 at 19:26
-
\$\begingroup\$ @SimonForsberg yes, I just write a program in Haskell to get the same output \$\endgroup\$Caridorc– Caridorc2015年09月13日 19:27:05 +00:00Commented Sep 13, 2015 at 19:27
1 Answer 1
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– Caridorc2015年09月13日 20:52:03 +00:00Commented Sep 13, 2015 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– Carsten S2015年09月13日 23:03:12 +00:00Commented Sep 13, 2015 at 23:03