D-flop with enable and clear, translated from VHDL to Haskell
I actually think your first attempt is the most readable. The advantage over the VDHL implementation is that you're annotating each case with a function name. This makes it more self-documenting.

I would just multi-line your if-statements, like this:

onTrue :: St -&gt; PIn -&gt; Bool -&gt; St
onTrue st PIn{..} edgeDetect = shouldReset
  where
    nullState = St 0
    shouldReset =
      if _reset
        then nullState
        else risingEdge
    risingEdge =
      if edgeDetect
        then shouldClear
        else st
    shouldClear =
      if _clear_n
        then nullState
        else enabled
    enabled =
      if _enable
        then st{ _out_1 = _in_1 }
        else st