Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type Lambda's in Scala: why is the extra parentheses needed in a declaration?

Intro:

According to my understanding the type declaration {type λ[α] = Either[A, α]} stands for any type which has an other type λ[α] as its member (in the exact same sense as methods are members of a class). This is a structural type, namely its structure is that it has the type alias declaration λ[α] as its member.

On the other hand, ({type λ[α] = Either[A, α]})#λ refers to only λ due to the type projection via #.

Question:

Why is the parentheses needed around {type λ[α] = Either[A, α]} when doing the type projection ? Why not just {type λ[α] = Either[A, α]}#λ ?

In other words, what is the exact parse tree for ({type λ[α] = Either[A, α]})#λ according to the Scala Type declaration grammar (see below) ?

Why is {type λ[α] = Either[A, α]}#λ not a correct "sentence" in this grammar ?

  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}
like image 724
jhegedus Avatar asked Nov 04 '14 09:11

jhegedus


1 Answers

You also need to consider

CompoundType    ::=  AnnotType {‘with’ AnnotType} [Refinement]
                  |  Refinement
Refinement      ::=  [nl] ‘{’ RefineStat {semi RefineStat} ‘}’
RefineStat      ::=  Dcl
                  |  ‘type’ TypeDef
                  |

informal description

# can only follow a SimpleType, but {type λ[α] = Either[A, α]} is a Refinement, which ultimately is a Type.

The only way to get a SimpleType from a generic Type is to surround it with parenthesis.

formal derivation

SimpleType
'(' Types ')' '#' id
'(' Type ')' # id
'(' InfixType ')' # id
'(' CompoundType ')' # id
'(' Refinement ')' # id
'(' '{' RefineStat '}' ')' # id
'(' '{' 'type' TypeDef '}' ')' # id
         ...
({ type λ[α] = Either[A, α] })#λ
like image 194
Gabriele Petronella Avatar answered Feb 22 '23 07:02

Gabriele Petronella