recursive matching with letfn