I'm coding a simple function in Haskell for my university assignment - the function should take an integer n and make an ascii triangle with the bottom row being 2*n 1 wide.
This is my implementation:
module Triangle where
data TArg = CallArg Int | RecursiveArg (Int, Int)
triangle :: TArg -> String
triangle (CallArg k) = triangle (RecursiveArg (k, k))
triangle (RecursiveArg (0, _)) = ""
triangle (RecursiveArg (k, q)) = triangle (RecursiveArg (k-1, q 1)) spaces stars spaces ['\n'] where
spaces = replicate q ' '
stars = replicate (k*2 - 1) '*'
Now, while it works - I don't like the necessity to specify the variant when calling the function, and would rather have some sort of coercion or a different way to specify two possible variations.
Thank you in advance
CodePudding user response:
It looks like you're trying to set up a recursive function with a call wrapper because the recursive call requires a second argument. I don't think your approach of encapsulating the arguments in a data structure is a good one. A more common approach is to create two functions, an outer function that you call from outside the definition, and an inner function to call recursively. By using scoping, you can hide the recursive inner function from the outside world. To acheive this, I would rewrite your code as follows
module Triangle where
triangle :: Int -> String
triangle k = triangle' k k where
triangle' :: Int -> Int -> String
triangle' 0 _ = ""
triangle' k q =
triangle' (k - 1) (q 1) spaces stars spaces "\n" where
spaces = replicate q ' '
stars = replicate (k * 2 - 1) '*'