ATTR Patterns 
    [   
    | 
    |   length : Int
    ]

ATTR Pattern Patterns
    [   
    | 
    |   vars USE { ++ } { [] } : { [Name] }
    ]
    
SEM Patterns
    | Cons lhs.length = 1 + @tl.length
    | Nil  lhs.length = 0
    

SEM Pattern
    | Variable              lhs.vars    = [ @name.self ]
    --  range                    : Range
    --  name                     : Name

    | As                    lhs.vars    = @name.self : @pattern.vars
    --  range                    : Range
    --  name                     : Name
    --  pattern                  : Pattern

{

patternAlwaysSucceeds :: Pattern -> Bool
patternAlwaysSucceeds p = 
    case p of
        Pattern_Variable _ _ -> True
        Pattern_Wildcard _ -> True
        Pattern_As _ _ p -> patternAlwaysSucceeds p
        Pattern_Parenthesized _ p -> patternAlwaysSucceeds p
        _ -> False

patternMatchFail :: String -> Range -> Core.Expr
patternMatchFail nodeDescription range =
    var "$primPatternFailPacked"
        `app_` packedString (
                    nodeDescription ++ " ranging from " ++ 
                    showPosition start ++ " to " ++ 
                    showPosition (getRangeEnd range) ++ " in module " ++
                    moduleFromPosition start
               )
    where
        start = getRangeStart range
}
