6

I'm thinking of a function like this:

> let applyN (initial : 't) (n:int) (f : 't -> 't) = seq {1..n} |> Seq.fold (fun s _ -> f s) initial;;

val applyN : initial:'t -> n:int -> f:('t -> 't) -> 't

> applyN 0 10 (fun x -> x + 1);;
val it : int = 10

Note: The code is F# but I tagged the question with haskell, ocaml and ml tags because if the function doesn't exist in F# libraries but it exists in other languages I would like to use the same name

5
  • 6
    can one of the downvoters please explain what the problem is here? The question seems good to me. FP subcommunities here usually are really friendly and I hope we can keep it that way, so please at least why the question is bad in your opinion. Commented Sep 24, 2015 at 9:08
  • 1
    I think you should post one question per language, as future people will probably search one answer. Mainly, I'd say if your question expects different answers, then you should split it. Commented Sep 24, 2015 at 9:38
  • 2
    @Carsten The levels of moderation noise seem to be higher than usual at the moment. Over the last couple of days I have seen not only odd downvotes but also absurd close votes in at least two [haskell] questions. Commented Sep 24, 2015 at 10:16
  • When a question is framed like "Where do I find X?" is very easily misunderstood as looking for off site resource or as lacking research. The next time you should frame your question to avoid such misunderstanding. Also if you are looking for something independent of the specific programming language you should use language-agnostic or simply functional-programming alone. Commented Sep 24, 2015 at 13:31
  • See also stackoverflow.com/questions/3911060/… for discussion of this function in Haskell. Commented Sep 24, 2015 at 14:02

4 Answers 4

7

You would have gotten (very close to) an answer by using for example Hayoo (or Hoogle, but Hoogle's not as flexible — iterateN was not found):

  • a search for Int -> (a -> a) -> a -> a revealed several functions that do what you want but are not part of the stdlib.

  • a search for applyN returned a function of exactly the same name with the type signature you are looking.

  • by laxing the return value by searching for Int -> (a -> a) -> a instead (note the missing -> a at the end), you get the iterateN :: Int -> (a -> a) -> a -> Seq a function which erdeszt has already mentioned.

P.S. Hoogle seems to be more capable of flipping around argument order: (a -> a) -> Int -> a -> Seq a successfully returns 'iterateN :: Int -> (a -> a) -> a -> Seq a`, which Hayoo does not.

Sign up to request clarification or add additional context in comments.

1 Comment

I didn't know you can search by signature. Thanks for the link to Hayoo!
3

There is an iterateN function for Haskell in the Data.Sequence module that looks like the one you are looking for.

It's actually just a combinaton of iterate + take: let iterateN n f x = take n (iterate f x) Here's an F# version of iterate (from here), Seq.take is part of the F# standard library:

let rec iterate f value = seq { 
   yield value
   yield! iterate f (f value) }

2 Comments

iterateN doesn't have the signature I'm looking for. The function should return the final value and not a sequence
@vidi You can always just take the last element(or you can inline the whole shebang inside iterateN and you don't have to build the collection).
1

A possible solution:

> import Data.Monoid
> import Debug.SimpleReflect -- not really needed, just for showing the result
> (appEndo . mconcat . replicate 5 . Endo $ f) a
f (f (f (f (f a))))

Another (already mentioned):

> iterate f a !! 5
f (f (f (f (f a))))

(add lambdas if you want to turn it into a function)

However, don't forget that Haskell is lazy: the above methods will first build a thunk by applying f many times and only then start evaluating. Sometimes f could be iterated in constant space, e.g. when f :: Int -> Int (and f itself works in constant space), but the above approaches only work in linear space.

I would define by own strict iteration combinator, e.g.:

iter :: Int -> (a -> a) -> a -> a
iter 0 _ x = x
iter n f x = iter (pred n) f $! f x

or even,

iter n f x = foldl' (flip $ const f) x [1..n]

which is more of less the Haskell translation of what was already posted in the question.

Alternatively, we can can define a strict version of iterate (which IMHO should already exist...)

iterate' :: (a -> a) -> a -> [a]
iterate' f x = x : (iterate' f $! f x)

Comments

0

To add to the list of other ways to do it,

import Control.Monad.State.Lazy

applyN initial n =
  flip execState initial . replicateM_ n . modify

Comments

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.