Selection handler for color picker At some point, I have this function which updates a color picker according the the mouse position, according to whether the user clicked a mouse button and according to its previous state:

updateColorPickerState :: ColorPicker -&gt; (GLfloat, GLfloat) -&gt; Bool -&gt; ColorPicker              
updateColorPickerState c (x,y) mouseClicked = if isPointWithinColorPicker c (x, y)
                                                then if mouseClicked
                                                  then if state c == Opened
                                                    then c {state = Idle, selectedColor = getColorAt (x',y')}
                                                    else c {state = Opened}
                                                  else if state c == Opened
                                                    then c
                                                    else c {state = Hovered}
                                                else if state c == Opened
                                                  then if mouseClicked
                                                    then c {state = Idle}
                                                    else c
                                                  else c {state = Idle}
                                              where (posX, posY) = pos c
                                                    (sizeX, sizeY) = openedSize c
                                                    x' = truncate ((x - posX) * 25 / sizeX)
                                                    y' = truncate (((-y) - posY) * 11 / sizeY)


How can I change the if-then-else tree to something more readable?
First, Simplify the function to a pattern match form.

updateColorPickerState :: ColorPicker -&gt; (GLfloat, GLfloat) -&gt; Bool -&gt; ColorPicker              
updateColorPickerState c (x,y) mouseClicked = 
  case isPointWithinColorPicker c (x, y) of
    True -&gt; case mouseClicked of
      True -&gt; case state c of
        Opened -&gt; c {state = Idle, selectedColor = getColorAt (x',y')}
        _      -&gt; c {state = Opened}
      False -&gt; case state c of
        Opened -&gt; c
        _      -&gt; c {state = Hovered}
    False -&gt; case state c of
      Opened -&gt; case mouseClicked of
        True -&gt; c {state = Idle}
        _    -&gt; c
      _      -&gt; c {state = Idle}
  where
    (posX, posY) = pos c
    (sizeX, sizeY) = openedSize c
    x' = truncate ((x - posX) * 25 / sizeX)
    y' = truncate (((-y) - posY) * 11 / sizeY)


Then, convert case-based pattern matches to function-based pattern matches.

updateColorPickerState :: ColorPicker -&gt; (GLfloat, GLfloat) -&gt; Bool -&gt; ColorPicker              
updateColorPickerState c (x,y) mouseClicked
    | isPointWithinColorPicker c (x, y) = mouseInside (state c) mouseClicked
    | otherwise                         = mouseOutside (state c) mouseClicked
  where
    -- mouse is inside bounding box
    mouseInside Opened True  = c {state = Idle, selectedColor = getColorAt (x',y')}
    mouseInside Opened False = c
    mouseInside _      True  = c {state = Opened}
    mouseInside _      False = c {state = Hovered}
    -- mouse is outside bounding box
    mouseOutside Opened False = c
    mouseOutside _      _     = c {state = Idle}
    (posX, posY) = pos c
    (sizeX, sizeY) = openedSize c
    x' = truncate ((x - posX) * 25 / sizeX)
    y' = truncate (((-y) - posY) * 11 / sizeY)