General problem
You can use foldl for this: in that case you pass an accumulator left-to-right over the list, and perform some operation over it:
So your compose then would look something like:
compose :: a -> [(a -> a)] -> a
compose x0 fs = foldl (??) x0 fs
So now the question is what we do in ??. The first argument is the accumulator, the second an element of the list, a function. So we have to implement something like:
compose :: a -> [(a -> a)] -> a
compose x0 fs = foldl g x0 fs
where g xi f = ...
we thus want to apply f to xi to obtain the next xi. Or in other words:
compose :: a -> [(a -> a)] -> a
compose x0 fs = foldl g x0 fs
where g xi f = f xi
If we aim to simplify the g function, we can write it as:
compose :: a -> [(a -> a)] -> a
compose x0 fs = foldl g x0 fs
where g = flip ($)
and further improve it to:
compose :: a -> [(a -> a)] -> a
compose = foldl (flip ($))
This then produces:
Prelude> foldl (flip ($)) 1 [(+1)]
2
Prelude> foldl (flip ($)) 1 [(+1),(+1)]
3
Prelude> foldl (flip ($)) 1 [(+1),(+1),(/2)]
1.5
Three or more elements
If you want to restrict the number of elements to three or more, we can use pattern matching:
compose :: a -> [(a -> a)] -> a
compose x0 fs@(_:_:_:_) = foldl (flip ($)) x0 fs
although it is a bit weird that the program is not supposed to work on lists with no, one or two elements.