Як вправу я пишу парсер для Haskell з нуля. Створюючи лексеру, я помітив наступні правила у звіті Haskell 2010 :
цифра → ascDigit | uniDigit
ascDigit →0
|1
| … |9
uniDigit → будь-який десятковий
октіт Unicode →0
|1
| … |7
hexit → цифра |A
| … |F
|a
| … |f
десяткова → цифра { цифра }
восьмерична → октіт { октіт }
шістнадцяткова → гексит { гексит }ціле число → десятковий |
0o
вісімковий |0O
вісімковий |0x
шістнадцятковий |0X
шістнадцятковий
поплавок → десяткова.
десяткова [ показник ] | десятковий показник
експонента → (e
|E
) [+
|-
] десятковий
Десяткові та шістнадцяткові літерали, поряд з плаваючими літералами, базуються на цифрі , яка допускає будь-яку десяткову цифру Unicode, а не ascDigit , яка допускає лише основні цифри 0-9 від ASCII. Як не дивно, восьмерика заснована на октіті , який замість цього допускає лише цифри ASCII 0-7. Я б здогадався, що ці "десяткові цифри Unicode" є будь-якими кодовими точками Unicode із загальною категорією "Nd". Однак сюди входять такі символи, як цифри повної ширини 0-0 та цифри Devanagari ०-९. Я бачу, чому може бути бажаним дозволити це в ідентифікаторах, але я не бачу ніякої користі за те, щоб дозволити писати ९0
для прямого 90
.
Здається, GHC зі мною згоден. Коли я намагаюся скласти цей файл,
module DigitTest where
x1 = 1
вона вигадує цю помилку.
digitTest1.hs:2:6: error: lexical error at character '\65297'
|
2 | x1 = 1
| ^
Однак цей файл
module DigitTest where
x1 = 1
компілює просто чудово. Чи неправильно я читаю специфікацію мови? Чи правильна (розумна) поведінка GHC насправді чи технічно це суперечить специфікаціям у Звіті? Я ніде не можу знайти згадки про це.