Most people would say that C is a top-down language (although I tend to tackle projects in a bottom-up way), whilst List/Forth/Python is a bottom-up language.
In a bottom-up approach, you create some feature that works, and then accumulate features from there.
Haskell has a nice repl, which I use all the time, so you could definitely call it a bottom-up language. Haskell, though, makes you think in a slightly different way from Lisp. If Lisp is a big ball of mud, then Haskell is a jigsaw puzzle. In Lisp, you just keep slapping on the clay until you arrive at your desired shape. With Haskell, the pieces have a definite “connectivity”, and must be assembled so that the connections match.
You have to think “one level up” from the feature you are working on. This tends to give Haskell a slower feel in terms of development speed, but I think ultimately leads to a better design that is easier to reason about. Haskell code is, I suggest, inherently easier to modify.
Let me give an example from something I have been working on earlier today: the parsing of command-line arguments. If you were working in C, you would probably have a whole lot of global/module variables that you toggle on or off as you process the arguments. Maybe you want to print a help message, give verbose output, select distinct processing paths, and so on.
In Haskell, this type of approach is rather “bitty”. Haskell doesn’t have state, although you could create a list of options. If you try to write C in Haskell, then you’ll probably end up with messier code than you would have in C. It’s time for a rethink.
My solution is to think about what the user is primarily trying to do in my program. They may be wanting help, print off a set of accounts, with or without downloading share price updates, or download share prices and print the days gains without printing off accounts.
The trick is to work out what the primary action is, and then dispatch on that action, with options. Haskell forces you to do a little thinking upfront. With Haskell, I would say that clean code is elegant, and ugly code is a nightmare. Haskell subtly forces you to write clean code. In C, you can just bang those rocks together.
What separates Haskell programmers from Lisp programmers is whether they consider it a feature (in the former case) or a bug (in the latter case).
Just my perspective from a newbie Haskell programmer.