Почему в вызовах типа "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, так далее.). Я бы посчитал это ошибкой в ​​грамматике.

Исправление этого также устранит необходимость $ печатать взломать.

Другие вопросы по тегам