为什么需要像"runSomeMonad $ do ..."这样的调用?

Pet*_*lák 32 syntax monads haskell do-notation

显然唯一可能的解释runSomeMonad do ...runSomeMonad (do ...).为什么不是Haskell语法允许的第一个变体?有些情况foo do bar可能实际上是模棱两可的吗?

Jon*_*rdy 26

请注意,您可以不只是观察到这种效果do,而且let,if,\,case,扩展mdoproc......和恐惧一元-.除了一元之外,我想不出一个含糊不清的案例-.以下是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 )
    | …
Run Code Online (Sandbox Code Playgroud)

恰好在fexp(函数应用程序)或aexp(文字表达式)中没有定义允许无特征化lexp(lambda let等)的情况.我认为这是语法中的一个错误.

修复这也将消除需要$打字黑客.

  • 多年前,我用这种方式修改语法的源代码构建了GHC,它确实似乎没有破坏任何东西(例如,它可以成功地重建自己).我特别喜欢将参数传递给块的调用,比如`withOpenFile path\handle - > do ...` (9认同)