@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.