2012-12-30 49 views
9

我在寫一個Haskell編譯器,我想盡可能多地實現Haskell 2010。我的編譯器可以解析一個模塊,但是爲程序完成模塊似乎是一項不重要的任務。我提出了棘手的,但也許有效,哈斯克爾模塊的一些例子:解決邊緣案例Haskell模塊導入和導出

module F(G.x) where 
    import F as G 
    x = 2 

這裏模塊F出口G.x,但G.x是一樣的F.x,所以模塊F出口x,當且僅當它出口x

module A(a) where 
    import B(a) 
    a = 2 

module B(a) where 
    import A(a) 

在這個例子中,要解決模塊A的出口,編譯器檢查aB進口是一樣的聲明a = 2,但B出口a,當且僅當A出口a

module A(f) where 
    import B(f) 

module B(f) where 
    import A(f) 

在解析模塊A,編譯器may've假設fB進口存在,這意味着A出口f,從而B可以導入A(f)和出口f。唯一的問題是沒有在任何地方定義的f :)。

module A(module X) where 
    import A as X 
    import B as X 
    import C as X 
    a = 2 

module B(module C, C.b) where 
    import C 
    b = 3 

module C(module C) 
    import B as C 
    c = 4 

這裏,module出口造成,出口列表是依賴於彼此和自己。

所有這些例子應該是有效的Haskell,由Haskell 2010規範定義。

我想問問是否有任何想法如何正確和完全實現Haskell模塊?

假定一個模塊只包含(簡單)變量綁定,import S(可能與asqualified),並可能有資格變量的出口列表和module ...縮寫。該算法必須能夠:

  • 計算每個模塊
  • 鏈接每個導出的變量與其結合
  • 鏈路每模塊中使用與其結合每(也許合格)可變的出口變量的有限列表

回答

9

您可能也有興趣A Formal Specification for the Haskell 98 Module System

我還介紹了一系列博客文章中的一些有趣的邊緣案例,其中只有first one已發佈到目前爲止。

最後,我正在研究 - 處理Haskell模塊的庫。它被稱爲haskell-names

根據您的目標,您可以簡單地在編譯器中使用它,研究源代碼或貢獻。 (你的例子會做出很好的測試用例。)


回答你的問題:遞歸模塊是通過計算一個固定點來處理的。

您從模塊圖中強連通的組件開始。對於此組件中的每個模塊,首先假定它不輸出任何內容。然後,您重新訪問這些模塊,並根據最新信息計算新的導出列表。你可以證明這個過程是單調的 - 每次導出列表增長(或者至少不縮小)。遲早會停止增長 - 那麼你已經達到了固定點。

您可以借用靜態分析的一些想法(該社區非常擅長計算固定點)來優化此算法,但是我的包當前實現了樸素算法(code)。

+0

哇,謝謝,我甚至不希望有實際的文件和圖書館針對這個問題:) –