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