Линзы неплохо обобщаются через профункторы: один интерфейс для разных операций; сложные операции выражаются через простую композицию "оптических элементов" (условно, как в гомоморфном шифровании).
А профункторная оптика, соответственно, расширяется до рефлексивной, и мы попадаем в мета-программирование.
-- Рефлексивное описание дварфа
dwarfSchema :: ReflectiveSchema
dwarfSchema = ReflectiveSchema
{ _fields =
[ ReflectiveField "name" stringLens [notEmpty] "Dwarf name"
, ReflectiveField "health" healthLens [range 0 100] "Health points"
, ReflectiveField "skills" skillsLens [validSkills] "Skill levels"
]
, _relationships =
[ Relationship "belongsTo" "fortress" fortressIdLens
, Relationship "hasMany" "items" itemsLens
]
}
-- Динамическое построение запросов
buildQuery :: String -> Query
buildQuery "dwarf.skills.mining > 10" =
Query $ dwarfSchema ^. field "skills" . field "mining" . filtered (> 10)
Оптику можно строить во время выполнения, генерация кода, конфигурируемые проекции.
Игрок может задавать собственные запросы... Но тоже нагрузочно конечно.
На хаскеле это всё красиво выглядит, но страшно далёк он от трудового итэ-народа.
