First impression, could be misinformed, but I'll bite.
Since a hardware circuit is a recursive function that takes a state of the hardware and produces a new state, starting from an initial state (and so is the universe where the initial state was supplied by the Big Bang), you can of course express it straightforwardly as a recursive function, which I think is what they sometimes do:
blinkerT (leds,mode,cntr) key1R = ((leds',mode',cntr'),leds)
where
-- clock frequency = 50e6 (50 MHz)
-- led update rate = 333e-3 (every 333ms)
cnt_max = 16650000 -- 50e6 * 333e-3
cntr' | cntr == cnt_max = 0
| otherwise = cntr + 1
mode' | key1R = not mode
| otherwise = mode
leds' | cntr == 0 = if mode then complement leds
else rotateL leds 1
| otherwise = leds
This is VHDL/Verilog spelled in Haskell (real hardware description languages will not make you spell the old state - leds,mode... - and the new state - leds',mode'... explicitly, which gets annoying for 20 state variables. Of course this could be taken care of by a preprocessor or a macro system, my point isn't that it's verbose but that it's VHDL spelled in Haskell, a bit awkwardly and maybe you can do it less awkwardly but the programming model is the same so calling it Haskell is cheating, kinda.)
This is definitely not what TFA is about - you don't represent the blinking leds as graph reduction, rather, you generate VHDL from VHDL-like Haskell.
This is not to say they aren't doing cool things in this project. If indeed they compile this:
fir coeffs x = dotp coeffs (window x)
where
dotp as bs = sum (zipWith (*) as bs)
...to efficient hardware description code, that's really cool. In general, I think that a sufficiently restricted functional language can compile very nicely to FPGA/hardware (and to DSPs and GPUs etc. etc.) I'm just saying that a general-purpose functional language is better targeted at a CPU, and that a functional language targeting something else is a DSL of sorts.