2

I was trying to recursively pass a function to itself a given number of times. So given the input in form of Function | RepeatNumber(Count) | Argument. So as an example if given the input: f 3 2 it would return f(f(f 2) This should then also work if the Function value where "square" it would Square the argument.

In terms of the logic I approached it as follows:

def repeatnew func count arg
    if count == 1 then (func arg)
    else (func (repeatnew func (count -1) arg))

I've been trying to research a solution to this for a while and I came across using Iterate and some other functions. Finally I came across this: https://wiki.haskell.org/Higher_order_function However I was unable to implement a working solution.

Edit: The solutions I did try to implement I could get compiling correctly, I am still very inexperienced with haskell and would appreciate an explanation on how to create a higher order function using my parameters.

5
  • I was unable to implement a working solution What was your specific issue that prevented your solution from working? What actual code did you try? Commented Mar 27, 2017 at 10:50
  • Just examples I tried: fpow f n x = iterate f x !! n repeatFun :: Char -> Int -> Char -> String repeatFun func count arg repeatFun = (count-1)*((func)+(arg)) repeatFun = func (repeatFun func (count-1) arg) I am new to haskell so my implementation skills are seriously lacking Commented Mar 27, 2017 at 10:54
  • 1
    Your post as it stands is missing a question, which is essential for a Q&A site. Please edit your post. If you've encountered any problems, add the "wrong" code and any error message you've got, or, if the behaviour was not what you expected, both the expected and actual behaviour. Commented Mar 27, 2017 at 10:57
  • Thank you for fixing the layout, in regards to a question, using the link I mentioned how can I implement a higher order function given my specific input. I should just be able to pass number of times to the loop, pass the argument to the function which is also take as an input parameter, but I struggle to convert that into actual haskell code. the solutions I tried as in my previous comment would not even compile and my limited knowledge of haskell doesnt help me finding a solution unfortunately. Commented Mar 27, 2017 at 11:03
  • "The solutions I did try to implement I could get compiling correctly, I am still very inexperienced with haskell and would appreciate an explanation on how to create a higher order function using my parameters." That sounds like you want your solution reviewed. For a review, head over to Code Review. Commented Mar 27, 2017 at 12:34

2 Answers 2

4

Spinning off from @Antisthenes' comment, One other way to do this is using the foldl1 with no base case.

pipeNTimes :: (a -> a) -> Int -> (a -> a)
pipeNTimes f n = foldl1 (.) $ replicate n f

pipeNTimes (*2) 3 2 -- returns 16
Sign up to request clarification or add additional context in comments.

1 Comment

+1 from me as this is a much more functional approach than my effort, I've learned quite a bit from this!
2

I am admittedly only a beginner at Haskell, so this may be a naive implementation, but I think this does what you are looking for:

applyRecursively f x y
    | x == 1 = f y
    | otherwise = f (applyRecursively f (x-1) y)

The applyRecursively function takes a function and two numbers as arguments.

If the middle argument (the count) is 1 then we apply the parameter function to the argument y. This is the edge case that stops the recursion.

The otherwise guard clause then calls recursively with the x parameter decremented, and applies function f to the result.

I have tested it using a lambda like this:

applyRecursively (\x -> x + 1) 3 3

It should add 1 to the values of 3 three times - it returns a value of 6 so it looks like it works.

As I say, I'm a beginner but I think this does what you're looking for.

4 Comments

It can be also implemented with simple if instead of guards. For more functional approach and codegolf it may also defined as: applyRecursively f n arg = foldr (.) id (replicate n f) $ arg For more codegolfing there is also point free version: applyRecursively = (foldr (.) id .). flip replicate
@Antisthenes I think my mind just melted! Functional programming still seems like magic sometimes when I'm trying to follow it, but many thanks for your code, that's really helpful.
@Antisthenes: how about applyRecursively f n arg = iterate f arg !! n?
@yatima2975: Yeah, it's also good idea. From the beginning i was thinking about writing point-free, which is why i've written it that way.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.