Предположим, я пишу функцию "замены" для типа данных абстрактного синтаксического дерева:
data Term = Id String
| If Term Term Term
| Let String Term Term
...
subst :: String -- name of identifier to replace
-> Term -- term to replace the identifier with
-> Term -- body in which to perform the replacements
-> Term
subst identifier term = go
where go (Id id') = if identifier == id' then term else Id id'
go (If t1 t2 t3) = If (go t1) (go t2) (go t3)
go (Let id' term' body) = Let id' (go term') (go body)
...
(Игнорировать проблемы с тенями).Обратите внимание, как утомительно писать ветку If
.Я должен сопоставить образец, назвав 3 части, а затем восстановить If
, применяя go
к каждой из 3 частей явно.Для Let
я должен сопоставить образец, назвав 3 части, и реконструировать Let
, применяя go
к соответствующим 2 частям в явном виде.Есть ли более простой (бессмысленный?) Способ написать это, не объясняя каждую деталь?