Trying to avoid imperative code

@jaror @anon58422685
Thanks for the help! I sat on this problem for the past few days. It’s interesting to see that both of your replies had a “before-after” pattern, as well as a function overloaded with pattern matching. However I wasn’t satisfied with the result when I tried to apply those patterns. Forgot exactly why. But there just always seemed to be a lot of wrapping and unwrapping, and much indented case expressions. I was reluctant to write new data structure or class instances as well. I thought I should be able to implement this with what Haskell gives me at default. It’s just a simple imperative idea that looks like:

if ( x == ENUM_1 )
  DrawA();
else
  DrawA_Edit();

if ( x == ENUM_2 )
  DrawB();
else
  DrawB_Edit();

...

Then I realized that I couldn’t really write this code well enough in an imperative language either. But I did manage to come up with a solution that doesn’t suck. First I still have the sum type, but I tried to not bundle data into it as much as before:

data NodeField
  = ActField
  | ServField
  deriving ( Eq, Generic, Ord )

Currently there are only two kinds of fields. But the idea should scale.

Then I put the drawing functions, and their variants in a such a dictionary:

let drawMap_Partial = Map.fromList
      [ ( ActField,  ( drawAct,  drawAct_Edit  ) ) 
      , ( ServField, ( drawServ, drawServ_Edit ) ) 
      ]

Then I have a deciding function that picks the correct drawing function, based on the condition:

f_PickFunc = \( field, ( f, f_Edit ) ) ->
  if field == editingField then f_Edit else f

  fs = List.map f_PickFunc ( Map.toList drawMap )

Finally I just sequence_ the list of drawing functions.

I’m still surprised that it’s hard to write good code for a task with a simple idea like this. But I’m glad that eventually, functional programming still managed to help me out on this.