3

Hi I'm new in Haskell programming. I'm trying to implement operator "++" by myself. Here's a small program I wrote but it won't work:

append (es:e) xs = 
    if (null es)
    then e:xs
    else append es (e:xs)

I received lots of type error with [a],[[a]] and [[[a]]]. Still confusing about the list type in Haskell. Can someone help me with that? Thank you. :)

1
  • @Bergi already explained how to rewrite this, but from reading your code I am getting the impression you were trying to pattern match on the last element of the list. If that were possible, your code would have been much closer to working. (You would still have been missing the empty list case.) However, Haskell lists are linked lists starting at the front and you can only pattern match elements from the front end. Commented Aug 26, 2014 at 14:34

1 Answer 1

20
append (es:e) xs =
        ^^^^

Typically, you would write (e:es), which could be spoken "one e before a list of es". You actually have used this meaning below, but have told the compiler that es is an element and e is a list - which produces the type errors you received.

    if (null es)

That's not how you should test for an emtpy list. In fact, if you'd call append [] … you'd get a "non-exhaustive pattern" error, because (e:es) is always a list of at least one element. So try two patterns:

append []     xs = xs
append (e:es) xs = append es (e:xs)

However, this still doesn't work expected - the first list is actually reversed by this snippet. Instead, the first element (e) needs to go before the whole rest of the list (es and xs):

append (e:es) xs = e : (append es xs)

(and that's indeed how ++ is implemented)

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

4 Comments

To be pedantic, there's a rewrite rule which replaces this definition of ++ with xs ++ ys = augment (\c n -> foldr c n xs) ys in actual optimised GHC Haskell.
@leftaroundabout: Ah, I see. I already wondered what that RULE thing meant :-)
@leftaroundabout Care to explain how that is an optimization? It appears to be something to do with list fusion, I just haven't encountered it before so I'm not entirely sure how it works.
@bheklilr augment gives optimization when it's combined with the fusion rule "foldr/augment" forall k z xs (g::forall b. (a->b->b) -> b -> b) . foldr k z (augment g xs) = g k (foldr k z xs), which ideally optimizes away most of the list allocation. augment differs from the similar build in that it's used to prepend stuff to a list rather than building the whole list. See GHC.Base.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.