[Haskell-cafe] Q about last&init

Richard A. O'Keefe ok at cs.otago.ac.nz
Fri Jul 18 00:54:11 UTC 2014


On 17/07/2014, at 9:35 PM, Закиров Марат wrote:

> I am teaching myself haskell. The first impression is very good...
> Anyway I am trying to backport my algorithm written in C. The key to
> performance is to have ability to remove element from the end of a
> list in O(1).

You can't.  Not in *any* programming language.  That's because
lists are one of many possible implementations of the "sequence"
concept, and they are optimised to support some operations at
the expense of others.  At the beginning level, you should think
of all Haskell data structures as immutable; fixed; frozen;
forever unchanged.  You can't even remove an element from the
front of a Haskell list, at all.  All you can do is to forget
about the original list and concentrate on its tail.

> But the original haskell functions last and init are O(n).

Haskell lists are singly linked lists.  Even by going to
assembly code, you could not make these operations O(1)
without *using a different data structure*.

> My questions are:
> 1) Is last function is something like "black box" written in C++ which
> perform O(1)?

No.

> 2) Or will optimizer (llvm?) reduce init&last complexity to 1?

No.

> 3) Some people suggest to use sequences package, but still how do they
> implement O(1) init&last sequences equivalent in haskell?

Well, you could try reading Chris Okasaki's functional data
structures book.

There is a classic queue representation devised for Lisp
last century which represents
  <a,b,c,d,e>
by ([a,b],[e,d,c])
so that you can push and pop at either end.
When the end you are working on runs out, you
reverse the other end, e.g.,
   ([],[e,d,c]) -> ([c,d,e],[]).

That can give you a queue with *amortised* constant time.
(There is a technical issue which I'll avoid for now.)

But let's start at the beginning.
You have an interesting problem, P.
You have an algorithm for it, A, written in C.
You want an algorithm for it, H, written in Haskell.
Your idea is to make small local syntactic changes
to A to turn in into H.
That's probably going to fail, because C just
loves to smash things, and Haskell hates to.
Maybe you should be using quite a different approach,
one that would be literally unthinkable in C.
After all, being able to do things that are unthinkable
in C is one of the reasons for learning Haskell.

Why not tell us what problem P is?


> 


More information about the Haskell-Cafe mailing list