5

Map and filter seem like they would be linear O(n) because they only have to traverse a list once, but is their complexity affected by the function being passed? For example are the two examples below of the same order?

map (+) list

map (complex_function) list
1
  • 2
    a good example might be filter isPrime [1..n] Commented May 24, 2015 at 8:08

3 Answers 3

6

In virtually all cases, when the documentation of an higher order function states its complexity is O(f(n)), this is assuming that the higher order function has constant time complexity O(1). Further, the exact meaning of n can vary, but when not explicitly stated it should be clear from the context: e.g. the length of a list, the number of elements/associations in a set/map, and so on.

Assume we have a higher order function g called as g h ... where h is a function and the ... are first order data. Without any other information about the higher-order function g, if the documentation states it's O(f(n)), you can get a more realistic worst-case bound of O(f(n)) * CostH where CostH represents the cost of calling H once.

Of course, CostH will also depend on which arguments are begin passed to h: here, all we know is that those arguments are being built in O(f(n)) time. It's hard to get a useful general bound on the size of the arguments for h since, for instance, if h takes trees as input, then you can build a very large tree in a short time:

foo :: Int -> Tree ()
foo 0 = Tree []
foo m = Tree [t,t] where t = foo (m-1)

The above builds a tree having 2^m leaves in m time (thanks to sharing). This can be adapted to 3^m or to b^m trivially keeping b*m complexity.

However, there might be some way to exploit parametricity to recover a more useful bound. For instance, if our order function has type

g :: (a -> Int) -> [a] -> Int

then we know that g h [...] can only call h with arguments taken from the list. Similarly, the library function call sortBy h [...] can only use h to compare two elements in the supplied list.

I have however no idea about how to formalize and prove the sketched claim above. It's quite possible that there are some research papers on the topic.

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

1 Comment

I'd never have thought about using parametricity to pull a time bound from thin air. I think it's of fairly limited utility though—whatever information you do give the function can be fed to a busy beaver or some such.
6

You seem to have a (common) misunderstanding that complexity is a function of n.

What is n?

n is just one parameter that measures something about your input. It might not be a sufficient (or even necessary) statistic for describing your input -- you might need other variables to accurately describe the complexity of your input.

So, map and filter are are linear in n. Their dependence on other variables depends on the function you pass, but their dependence on n generally doesn't.

(Footnote: yes, you can pass a function to map and filter that actually performs more work as it processes more elements, but that's uninteresting and beside the point I'm trying to make here.)

3 Comments

Are you sure about that footnote? I don't see how you could do such a thing, although traverse and filterM certainly can. Am I missing something?
@dfeuer: I think so? Just append every element you see to an array, and perform an extra dummy scan through the entire array before doing so.
You can only do that from a function that's been passed to map or filter if you're using unsafePerformIO
3

For some background on complexity and higher-order functions, see, e.g.,

Hofmann, Martin. An Application of Category-Theoretic Semantics to the Characterisation of Complexity Classes Using Higher-Order Function Algebras.

Bull. Symbolic Logic 3 (1997), no. 4, 469--486. https://doi.org/10.2307/421100

1 Comment

It would be a good idea to summarize some of the main points (especially with regard to the question) since that's an offsite link (link-only answers are discouraged here) and it also requires a subscription to view.

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.