您可以在列表中使用特殊语法来自定义数据类型吗?

时间:2014-07-02 23:44:25

标签: haskell ghc

据称,列表定义为:data List a = Null | Cons a (List a), 但是我们都知道它有特殊的语法。我可以看到:如何只是Cons类型构造函数的别名,但是1)这个语法是如何/在哪里实现的; 2)我可以为另一个数据类型定义我自己的特殊语法,比如{ {1}} Yesod使用。

感谢。

4 个答案:

答案 0 :(得分:5)

列表语法在编译器的源代码中定义。

莎士比亚使用的语法称为“准指数”语法,它也是编译器中定义的特殊语法。你可以制作自己的准引号。

答案 1 :(得分:5)

您可能正在寻找OverLoadedlists ghc扩展程序。这允许您使用列表语法[1,2,3]来初始化和模式匹配向量,集和其他结构。链接提供了一些如何设置列表重载的示例。

[1, 2, 3, 4, 2] :: Set Int
[1, 2, 3, 4, 5] :: Vector Int

它目前不处理异构列表,也不会过载:运算符。

您可能需要阅读trac page on the extension

如果您正在寻找一个通用的cons运算符,您应该查看中的Control.Lens.Cons模块 lens包。特别是<| operator。从hackage文档复制:

>>> a <| []
[a]
>>> a <| Seq.fromList []
fromList [a]

答案 2 :(得分:1)

<强> 1。如何创建自己的二元运算符?

您可以通过在括号中包装运算符名称(完全由符号构成)并为其定义来实现此目的。在您提到的情况下,如果您有数据构造函数:

data List a = Cons a (List a) | Nil

然后你可以定义:

(:) :: a -> List a -> List a
(:) = Cons

至于它的实施位置,它是in the standard prelude

data  [a]  =  [] | a : [a]  deriving (Eq, Ord)
-- Not legal Haskell; for illustration only

(那个评论也存在) - 我认为列表的实际实现是由编译器隐藏的(因为括号是语法糖),但它包含在Prelude中。

<强> 2。如何定义自定义语法?

Hamlet语法是QuasiQuoter的一个例子,它使用Template Haskell实现,{{3}}是一组用于元编程Haskell的系统。像这样的自定义语法通常很难定义。

答案 3 :(得分:1)

如果您需要自己的中缀数据构造函数,请以合法的运算符名称开头,然后以冒号(':')开头,例如:

data ExprF r = Lit Integer | r :+: r | r :*: r