Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Repeating function recursive in Haskell

Tags:

haskell

I am trying to make a function that outputs char*m n times, as such as the expected output would be ["ccc","ccc"] for the input 2 3 c. Here is what i have so far:

rectangle :: Int -> Int -> Char -> [string]
rectangle n m c 
    | m > 0 = [concat ([[c]] ++ (rectangle n (m-1) c))] 
    | otherwise = []

I am able to carry out the first part, char*m, so it returns ["ccc"]. Thing is: I also would like to be able to repeat my string n times.

I have tried using replicate but it doesn't seem to work, yet it works if doing it in the console: replicate 2 (rectangle 2 3 c).

like image 682
Lunar Avatar asked Apr 11 '26 12:04

Lunar


2 Answers

Try the replicate function this way:

replicate :: Int -> a -> [a]

rectangle n m c = replicate n (replicate m c)

Also, don't forget to mention if this is homework.

like image 142
Aaa Avatar answered Apr 13 '26 03:04

Aaa


As an addendum to Refactor's answer, I think his approach is the correct one. He subdivides the problem until it can be solved trivially using built-in functions. If you want to roll your own solution for learning purposes, I suggest you keep this subdivision, and go from there, implementing your own replicate. Otherwise, you will end up with a single function which does too much.

So the remaining problem is that of implementing replicate. My first idea would be to look at the source code for replicate. I found it via hoogle, which led me to hackage, which has links to the source code. Excerpted from the source:

replicate               :: Int -> a -> [a]
replicate n x           =  take n (repeat x)

which is nice and concise, again using the built-in functions. If you want to completely roll your own replicate, you can do:

myReplicate                 :: Int -> a -> [a]
myReplicate n x | n <= 0    = []
                | otherwise = x : replicate (n-1) x

----------EDIT----------------

As a side note, I think your problem requires two rather orthogonal skills. The first is trying not to tackle the whole problem at once, but making some small progress instead. Then you can try to solve that smaller problem, before returning to the larger. In your case, it would likely involve recognizing that you definitely need a way of transforming the character into a series of characters of length n. Experience with functions such as map, filter, foldr and so on will help you here, since they each represent a very distinct transformation, which you might recognize.

The second skill required for your solution - if you want to roll your own - is recognizing when a function can be expressed recursively. As you can see, your problem - and indeed many common problems - can be solved without explicit recursion, but it is a nice skill to have, when the need arises. Recursive solutions do not always come easily mind, so I think the best way to gain familiarity with them are to read and practice.

For further study, I'm sure you have already been pointed to the excellent Learn You a Haskell and Real World Haskell, but just in case you haven't, here they are.

like image 27
Boris Avatar answered Apr 13 '26 04:04

Boris



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!