まず,cofree annotationを使う動機から説明すると,構文木を扱う際各木に注釈情報を埋め込みたい時があって(例えば,パース時のソースコード上の位置や,型情報など),このような情報はコンパイル時どんどん変遷していくため,決めうちじゃなくて何らかの型変数にしておきたいということがあります.
ただ,これを単純に実現すると,
data Expr a = Val Int a | Add (Expr a) (Expr a) a
というように注釈情報を埋め込みたい場所に一々型変数を書かなければいけません.これを何とかしたいというのが動機です