TL; DRГетерогенный Список для DSL
является их способ, которым я могу построить гетерогенную список ограниченного в какой-то класс типов, без вызова конструктора по каждому элементу?
я, наконец, есть возможность принять более глубокое погружение в Haskell, и я пытаюсь построить DSL, который генерирует строку запроса для SQL как язык. Ниже приведен псевдокод для того, что я пытаюсь попытаться, эти типы будут более усовершенствованы, как только я получу лучшее представление о том, как подойти к этому. Пожалуйста, извините неясность.
Нужный синтаксис для моего DSL-то вроде
from :: String -> Query
select :: [String] -> Query -> Query
select ["this", "that"] $ from "tbl"
беда в том, что я хотел бы, чтобы такие вещи, как столбец арифметических и логических операторов в аргументе для выбора. Например
(<~) :: String -> Column -> Column -- used for assigning a new name
add :: String -> String -> Column
select ["stuff" <~ "this" `add` "that", "this"] $ from "tbl"
выход которого может быть что-то вроде
SELECT
this + that as stuff,
this
FROM tbl;
Очевидная проблема в том, что это требует гетерогенный список. Я мог бы создать новый тип данных, чтобы обернуть эти значения и идти дальше с моей жизнью, но я думаю, что результат является гораздо более громоздким
select ["stuff" <~ (Column "this") `add` (Column "that"), Column "this", Column "that"] $ from "tbl"
Я видел некоторые трюки с помощью GADT-х и экзистенциалов, но все они требуют намотав каждый значение в конструкторе, в то время как я упрямо хочу, чтобы мои строки были такими, какие есть. Является ли это возможным??
Не так, но вы можете использовать Template Haskell для создания некоторого пользовательского синтаксиса. Предупреждение: не для слабонервных. Кроме того, есть несколько трюков, которые вы можете играть с классами, чтобы упростить запись гетерогенных списков (пакет 'HList' имеет такую вещь). Это будет выглядеть красиво, но ваши сообщения об ошибках будут страшными. – dfeuer