2016-10-30 19 views
5

我正在學習haskell,並且在解決我碰到的許多haskell表達式時,我有很多困難。如何自動將任意haskell表達式括起來?

當然,我認爲,在足夠的練習下,心理解析haskell將成爲第二性質,但與此同時,爲了理解我遇到的情況,我想找到一些自動的方法來將任意「標準haskell」表達式轉換爲其中通過引入必要括號來消除所有「不明確」子表達式的表達式。

例如,將轉化的表達

f g h i 

...成

((f g) h) i 

...,或

a -> b -> c -> d 

...成

a -> (b -> (c -> d)) 

...等

最好,這將是一個工具,我可以用我的電話訪問,因爲我做很多我的閱讀對哈斯克爾遠離正確的計算機。


當然,沒有這樣的工具可能可能與未知的固定性和關聯的運營商定製合作。通過「標準哈斯克爾」我的意思是在前奏和標準哈斯克爾庫中定義的東西。

我使用的是「曖昧」這裏簡寫「在沒有優先規則不明確」。例如。 2 + 3 * 5不明確除非有一些優先規則解決了兩個操作中的哪一個首先被執行的問題。

+0

我不能老是想着你的_phone_任何東西,但也有一些非常簡單的事情,你可以在GHCI – Alec

+0

好做,[哈斯克爾-SRC-EXTS(HTTP://hackage.haskell。 org/package/haskell-src-exts-1.18.2/docs/Language-Haskell-Exts.html)可以很容易地獲得完全明確的分析樹並將其打印出來。但它不可讀。嘗試'(fmap。fmap。fmap)(const())(parseFile「foo.hs」)'ghci,一旦你安裝了它。 –

+0

@Alec:我可以在ghci中做什麼? (關於電話:這只是一個偏好,如果在這件事上有一個選擇,如果沒有,我會很樂意接受ghci。) – kjo

回答

9

如果你真的想去它的工作,你可以寫一個TemplateHaskell函數爲你做這個 - 你基本上只是走AST,並隨意添加parens。我開始這樣做,但意識到它會很快很乏味。我覺得現在可能會更方便,因爲只有在實際進場時才考慮咖喱(帶有未完全應用的功能)。


但是,你可以使用你的問題的一個子情況一招:各地運營商,其固定性和結合你不熟悉的括號。在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> 

但是,這絕對不會固定類型簽名或功能的應用程序,你想要的方式。

4

這是你問的不完全是,但我一直在使用HLint發現警告我不必要的括號,當我寫哈斯克爾是一個很大的幫助,當我讀

您還可以在Bernie Pope's "A tour of the Haskell Prelude"的頁23找到有用的圖表。我已經在下面包含一個副本。

page 23 of Bernie Pope's "A tour of the Haskell Prelude"