DSL的异构列表

时间:2016-02-04 20:30:55

标签: haskell types dsl existential-type gadt

TL; DR

是他们可以构建一个约束到某个类型类的异构列表的方法,而不需要在每个元素上调用构造函数吗?

我终于有机会深入了解Haskell,我正在尝试构建一个为SQL语言生成查询字符串的DSL。以下是我试图尝试的伪代码,一旦我更好地了解如何处理这些类型,这些类型将更加精细。请原谅模糊。

我的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和Existentials的技巧,但它们都需要在构造函数中包装每个值,而我固执地希望我的字符串不变。有可能??

2 个答案:

答案 0 :(得分:2)

GHC对案件的扩展名就像这样:OverloadedStrings。 OverloadedStrings背后的基本思想是字符串文字可以是实现Data.String.IsString类型类的任何类型。所以对于你的代码,你可以做这样的事情。

import Data.String

newtype Column = Column String

instance IsString Column where
  fromString = Column

然后按原样定义你的组合子。现在,您想要的裸字符串文字将被解释为Columns

Main*> :t ["those" <~ "this" `and` "that", "thing"]
["those" <~ "this" `and` "that", "thing"] :: [Column]

答案 1 :(得分:0)

不,在Haskell中不可能使用正确的异构列表。你总是需要某种构造函数。但是,您的问题可能还有另一种解决方案。您可以重新定义组合器以返回 $("div[checkboxids]").hide(); $("input:checkbox").click(function() { // Hide all the div $("div[checkboxids]").hide(); // Enable respective divs only $("input:checked").each(function() { $("div[checkboxids*='" + $(this).attr("id") + "']").show(); }); }); 而不是String s。或许这样的事情。

Column