Re-implementing basic list operations
foldl'

Your implementation is fine, but generally, seq is written infix, like a `seq` b. Therefore, I’d write it like this:

foldl' :: (b -&gt; a -&gt; b) -&gt; b -&gt; [a] -&gt; b
foldl' f accumulator [] = accumulator
foldl' f accumulator (x:xs) =
    accumulator' `seq` foldl' f accumulator' xs
  where accumulator' = f accumulator x


I’ve also indented the second to last line to visually distinguish it more from the where clause.

foldr

Your implementation looks good to me.

length

You mention that you’re explicitly avoiding fold, but why? There’s no reason to avoid it here. Still, even without using it, your implementation can be improved.

Usually, helper functions like length' are nested inside a where clause, sometimes idiomatically named go. Additionally, your 1-element case is unnecessary, since (x:xs) will match a 1-element list. Finally, your use of an accumulator is pointless, since you never actually change it from 0, and your function isn’t tail recursive. Therefore, I would write length like this if you really want to avoid a fold:

length :: [a] -&gt; Int
length = go 0
  where go accumulator [] = accumulator
        go accumulator (x:xs) = go (accumulator + 1) xs


This actually uses the accumulator, which allows it to be tail recursive.

map

Again, I would use a fold here. An implementation with foldr would look like this:

map :: (a -&gt; b) -&gt; [a] -&gt; [b]
map f = foldr (\x xs -&gt; f x : xs) []


However, if you want to write the recursion manually, your 1-element case is once again redundant. You could simplify your implementation to this:

map :: (a -&gt; b) -&gt; [a] -&gt; [b]
map _ []     = []
map f (x:xs) = f x : map f xs


filter

Once again, I would use a fold here:

filter :: (a -&gt; Bool) -&gt; [a] -&gt; [a]
filter f = foldr (\x xs -&gt; if f x then x : xs else xs) []


If you want to use explicit recursion, though, your implementation looks fine.

(++)

Your 0-element case is redundant here because foldr will handle the 0-element case just fine on its own. You can eliminate it entirely:

(++) :: [a] -&gt; [a] -&gt; [a]
xs ++ ys = foldr (:) ys xs