Почему в вызовах типа "runSomeMonad $ do ..." должен быть знак $?
Видимо единственно возможная интерпретация runSomeMonad do ...
является runSomeMonad (do ...)
, Почему первый вариант не допускается синтаксисом Haskell? Есть ли какой-то случай, когда foo do bar
может быть на самом деле неоднозначно?
1 ответ
Обратите внимание, что вы можете наблюдать этот эффект не только do
, но также let
, if
, \
, case
, расширения mdo
а также proc
... и страшный унарный -
, Я не могу вспомнить случай, в котором это неоднозначно, за исключением одного -
, Вот как определяется грамматика в Языковом отчете Haskell 2010, §3: Выражения.
exp
→ infixexp :: [context =>] type
| infixexp
infixexp
→ lexp qop infixexp
| - infixexp
| lexp
lexp
→ \ apat1 … apatn -> exp
| let decls in exp
| if exp [;] then exp [;] else exp
| case exp of { alts }
| do { stmts }
| fexp
fexp
→ [fexp] aexp
aexp
→ ( exp )
| …
Просто случается, что ни один случай не определен в fexp
(функция приложения) или aexp
(буквальное выражение), что позволяет без скобок lexp
(Лямбда, let
, так далее.). Я бы посчитал это ошибкой в грамматике.
Исправление этого также устранит необходимость $
печатать взломать.