我正在学习haskell,我在心理上解析我遇到的许多haskell表达式时遇到了很多困难.
当然,我希望通过足够的练习,精神上解析haskell将成为第二天性,但与此同时,为了理解我所遇到的,我想找到一些自动翻译任意的方法"标准haskell" 1表达式,其中通过引入必要的括号消除了所有"模糊的" 2个子表达式.
例如,它会翻译表达式
f g h i
Run Code Online (Sandbox Code Playgroud)
......进入
((f g) h) i
Run Code Online (Sandbox Code Playgroud)
..., 要么
a -> b -> c -> d
Run Code Online (Sandbox Code Playgroud)
......进入
a -> (b -> (c -> d))
Run Code Online (Sandbox Code Playgroud)
......等
最好,这将是我可以使用我的手机访问的工具,因为我在远离正确的计算机上阅读haskell的大部分内容.
1当然,没有这样的工具可能适用于未知固定性和关联性的自定义操作符."标准haskell"是指前奏和标准haskell库中定义的内容.
2我在这里使用"含糊不清"作为"在没有优先规则的情况下模棱两可"的简写.除非有一些优先规则解决了首先执行两个操作中的哪个操作的问题,否则 Eg 2 + 3 * 5是不明确的.
Ale*_*lec 10
如果你真的想要去做它的工作,你可以编写一个TemplateHaskell函数为你做这个 - 你基本上只是走AST并随意添加parens.我开始这样做了,但意识到它会变得非常冗长乏味.我认为现在可能更方便你只考虑实际发挥作用时的currying(功能没有完全应用).
但是,您可以使用一个技巧来解决问题的一个子问题:围绕运营商的问题,这些运营商的固定性和关联性是您不熟悉的.在GHCi中,在使用正确的标志启动之后,只需将您感兴趣的表达式包装在中$([| <expression> |]).然后,您可以在评估结果之前查看表达式的括号版本.
$ ghci -ddump-splices -XTemplateHaskell
Prelude> $([| 1 + 2 ^ 3 * 4 |])
<interactive>:1:3-21: Splicing expression
[| 1 + 2 ^ 3 * 4 |] ======> (1 + ((2 ^ 3) * 4))
33
Prelude> $([| 1 <$ pure 4 >>= \x -> const mempty =<< [(+),(*)] <*> [1,2] <* [False] |])
<interactive>:2:3-77: Splicing expression
[| 1 <$ pure 4
>>=
(\ x_a6PT -> const mempty =<< [(+), (*)] <*> [1, 2] <* [False] |]
======>
((1 <$ (pure 4))
>>=
(\ x_a6PT
-> ((const mempty) =<< (([(+),(*)] <*> [1,2]) <* [False]))))
[]
Prelude>
Run Code Online (Sandbox Code Playgroud)
但是,这绝对不会以您希望的方式修复类型签名或函数应用程序.