I was reading 'Category Theory for Programmers' by Bartosz Milewski and got really confused by the implementation of bimap in Bifunctor typeclass.
class Bifunctor f where
bimap :: (a -> c) -> (b -> d) -> f a b -> f c d
bimap g h = first g . second h
first :: (a -> c) -> f a b -> f c b
first g = bimap g id
second :: (b -> d) -> f a b -> f a d
second = bimap id
This is the definition of the Bifunctor typeclass taken directly from the library Control. If bimap evaluates to first and second, which in turn evaluates to bimap itself, how is this supposed to end? Could you please explain how the evaluation of bimap works? Thank you!