Functional programming is an odd beast for me. I learned F# and Haskell, wrote a few simple programs and love using them, but never had the "flash of revelation" that some people talk about. But slowly, I noticed that more and more I was writing code that was meant to be immutable, breaking up tasks into more, smaller functions, and trying to use delegates a lot more. Its a thing that, if you like it, creeps into your work because the value of those techniques are self-evident.
Now, more practically for training:
I find that two concepts really click Functional Programming as a style to me.
First, FP style is based on structure of data, not composition as in OOP. I looked at something like List in C# as being a clever trick to generate type-safe lists, something that composed the type (string) into the other type (list). After learning FP, I look at generics more like Monads now. List is a structured form that code can take, and it decorates the strings.
Second, and perhaps more useful to C#/ASP programmers, is the idea that FP works on recursion and repetition, while OOP works on mutability and looping. I tend to think of the ASP page lifecycle as a kind of FP now: each request is processed from scratch through the entire life-cycle, so the entire page is, in effect, one big slowly recursing program. If you can narrow that notion down, you get a better idea of how an imperative program can be structured around loops of functions that take in data, operate over it, and return out new data instead of modifying the old.
The trickiest hurdle, at least for me, to overcome with this approach is that sinking feeling that you're wasting tons of resources when using mutable objects would save a ton of memory. In GC we trust, and I just had to learn to let go of performance concerns until I'd actually seen the program run and verified if there even were any, and if so to use a profiler to see exactly where the problems were.
make
is more of a declarative language than F# or Caml! (Ironically, this makes your job easier. )