说明:
根据我的理解,类型声明{type λ[α] = Either[A, α]}
代表任何具有其他类型λ[α]
作为其成员的类型(与方法是类的成员完全相同)。这是一种结构类型,即它的结构是它具有类型别名声明λ[α]
作为其成员。
另一方面,由于({type λ[α] = Either[A, α]})#λ
的类型投放,λ
仅指 #
。
问题:
为什么在进行类型投影时,括号需要{type λ[α] = Either[A, α]}
左右?为什么不只是{typeλ[α] = [A,α]}#λ?
换句话说,根据Scala Type declaration grammar(见下文), ({type λ[α] = Either[A, α]})#λ
的确切解析树是什么?
为什么{type λ[α] = Either[A, α]}#λ
在这个语法中不是正确的“句子”?
Type ::= FunctionArgTypes ‘=>’ Type
| InfixType [ExistentialClause]
FunctionArgTypes ::= InfixType
| ‘(’ [ ParamType {‘,’ ParamType } ] ‘)’
ExistentialClause ::= ‘forSome’ ‘{’ ExistentialDcl
{semi ExistentialDcl} ‘}’
ExistentialDcl ::= ‘type’ TypeDcl
| ‘val’ ValDcl
InfixType ::= CompoundType {id [nl] CompoundType}
CompoundType ::= AnnotType {‘with’ AnnotType} [Refinement]
| Refinement
AnnotType ::= SimpleType {Annotation}
SimpleType ::= SimpleType TypeArgs
| SimpleType ‘#’ id
| StableId
| Path ‘.’ ‘type’
| ‘(’ Types ‘)’
TypeArgs ::= ‘[’ Types ‘]’
Types ::= Type {‘,’ Type}
答案 0 :(得分:12)
您还需要考虑
CompoundType ::= AnnotType {‘with’ AnnotType} [Refinement]
| Refinement
Refinement ::= [nl] ‘{’ RefineStat {semi RefineStat} ‘}’
RefineStat ::= Dcl
| ‘type’ TypeDef
|
#
只能关注SimpleType
,但{type λ[α] = Either[A, α]}
是Refinement
,最终是Type
。
从通用SimpleType
获取Type
的唯一方法是用括号括起来。
SimpleType
'(' Types ')' '#' id
'(' Type ')' # id
'(' InfixType ')' # id
'(' CompoundType ')' # id
'(' Refinement ')' # id
'(' '{' RefineStat '}' ')' # id
'(' '{' 'type' TypeDef '}' ')' # id
...
({ type λ[α] = Either[A, α] })#λ
答案 1 :(得分:8)
#
需要SimpleType
:
SimpleType ‘#’ id
但是,{ … }
是Refinement
(请参阅CompoundType
),除非带括号(SimpleType
),否则不是‘(’ Types ‘)’
。
因此,({type λ[α] = Either[A, α]})#λ
的解析树如下:
SimpleType ‘#’ id
/ \
‘(’ Types ‘)’ 'λ'
|
Type
=
InfixType
=
CompoundType
=
Refinement