### Haskell Stacks : Two Different Ways

I am starting to attempt to understand how Haskell can persist functions sans the variables. You can do it with lists, already. There are plenty of functions that demonstrate the concept. But I want to expand further. I want to try implementing a stack with a list, and then do it with a recursive type. This is what I have for the first one:

I thought the reverse function was neat, but seemingly costly. But, from the Prelude:

We can see a really slick way of doing reverses. "reverse" is merely a function curry of a foldl waiting for the last parameter. Let's see if it is costly:

So, the ones with the same indentation are the same, except the second line is the flip function evaluated. It is what I expected, though. It takes O(n) (?) time (there are two operations on the data: one operation to flip, and another operation to add to the new list. So, maybe it is O(2n)? I forget my algorithm lessons.) It seems though, that the original implementation I provided performs the same though. Maybe expressing it via reverse then is easier.

Lists are, still probably still efficiently implemented, and those operations I am doing are turned into an iteration (tail-call recursion), plus some other magic I don't know about. I have to think of a nifty way of handling it faster though.

Anyway, the other idea I had was to make a stack a recursive data type:

What a wacky idea. I have to think about this one, and read some common examples on this.

putAtEnd [] item = [item]

putAtEnd (x:xs) item = x : putAtEnd xs item

push lst item = putAtEnd lst item

-- or

-- push lst item = reverse (item : (reverse lst))

pop lst = pop_ lst ((length lst) - 1)

pop_ _ 0 = []

pop_ (x:xs) len = x : pop_ xs (len - 1)

-- or

-- pop lst = reverse (tail (reverse lst))

I thought the reverse function was neat, but seemingly costly. But, from the Prelude:

reverse :: [a] -> [a]

reverse = foldl (flip (:)) []

flip f x y = f y x

foldl f z [] = z

foldl f z (x : xs) = foldl f (f z x) xs

We can see a really slick way of doing reverses. "reverse" is merely a function curry of a foldl waiting for the last parameter. Let's see if it is costly:

reverse [1,2,3,4]

-> foldl (flip (:)) [] [1,2,3,4]

-> foldl (flip (:)) (flip [] 1) [2,3,4]

-> foldl (flip (:)) (1 : []) [2,3,4]

-> foldl (flip (:)) (flip [1] 2) [3,4]

-> foldl (flip (:)) (2 : [1]) [3,4]

-> foldl (flip (:)) (flip [2,1] 3) [4]

-> foldl (flip (:)) (3 : [2,1]) [4]

-> foldl (flip (:)) (flip 4 : [3,2,1]) []

-> foldl (flip (:)) [4,3,2,1] []

-> [4,3,2,1]

So, the ones with the same indentation are the same, except the second line is the flip function evaluated. It is what I expected, though. It takes O(n) (?) time (there are two operations on the data: one operation to flip, and another operation to add to the new list. So, maybe it is O(2n)? I forget my algorithm lessons.) It seems though, that the original implementation I provided performs the same though. Maybe expressing it via reverse then is easier.

Lists are, still probably still efficiently implemented, and those operations I am doing are turned into an iteration (tail-call recursion), plus some other magic I don't know about. I have to think of a nifty way of handling it faster though.

Anyway, the other idea I had was to make a stack a recursive data type:

data Stack n m = Item m | StackFrame ((Stack n) (Item m))

-- so ...

(StackFrame (StackFrame (Item 1) (Item 2)) (Item 3))

-- looks like

-- 3

-----

-- 2

-----

-- 1

-----

What a wacky idea. I have to think about this one, and read some common examples on this.