I agree that the same name should be the same type (or kind of type). The general unfold should have an unfolder with an option in the result. Note, in that case, the unfolder is what they also call a reader: 'state -> ('item * 'state) option