Введите Lambda в Scala: зачем нужны дополнительные скобки в декларации?
Введение:
В соответствии с моим пониманием объявление типа {type λ[α] = Either[A, α]}
обозначает любой тип, у которого есть другой тип λ[α]
как его член (в том же смысле, что и методы, являются членами класса). Это структурный тип, а именно его структура состоит в том, что он имеет объявление псевдонима типа λ[α]
в качестве его члена.
С другой стороны, ({type λ[α] = Either[A, α]})#λ
относится к только λ
из-за проекции типа через #
.
Вопрос:
Почему круглые скобки нужны для {type λ[α] = Either[A, α]}
при выполнении проекции типа? Почему не просто {type λ [α] = Либо [A, α]} # λ?
Другими словами, то, что является точным деревом синтаксического анализа для ({type λ[α] = Either[A, α]})#λ
в соответствии с грамматикой описания Scala (см. ниже )?
Почему {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}
Ответы
Ответ 1
Вам также необходимо рассмотреть
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, α] })#λ
Ответ 2
#
требуется SimpleType
:
SimpleType ‘#’ id
Однако { … }
является Refinement
(см. CompoundType
), который не является SimpleType
, если не заключен в скобки (см. ‘(’ Types ‘)’
).
Итак, дерево разбора ({type λ[α] = Either[A, α]})#λ
выглядит следующим образом:
SimpleType ‘#’ id
/ \
‘(’ Types ‘)’ 'λ'
|
Type
=
InfixType
=
CompoundType
=
Refinement