2011-11-29 36 views
10

我一直在玩一個完全的類型安全AST等創建使用GADTs和Haskell中完全類型DSEL,它似乎是做了正確輸入編譯器要求的結構,如從哈斯克爾類型的地圖到類型和值(類型化的環境)以及Haskell類型系統都可以理解的類型和值。 C++具有Boost.Fusion庫,其結構像這些(類型 - >值映射,類型值向量等)。 Data.Tuple處理序列,但Haskell版本的東西,如Boost.Fusion map s?哈斯克爾相當於Boost.Fusion

+0

downvote的原因是什麼? –

+0

當你描述一個「編譯器」時,你要從哪個表編譯?如果你有GADT,你是真的在爲它編寫解釋器,還是從GADT到例如C代碼的函數? – sclv

+0

要麼 - 將任何類型的AST翻譯成其他任何東西或運行它的任何問題都會出現。 –

回答

10

看那dependent-map包。我自己並沒有使用它,但它似乎是按照你所要求的。如果您需要真正使用類型(和類型)相等,那麼您可能需要同意默認值或使用TypeRep作爲關鍵字。

1

您是否在尋找Data.Map,並列出? (例如[Int])。

+0

沒有,因爲元素需要有不同的類型,這裏的鍵類型。我想要一個像'(Int-> 5,Float - >「foo」)'這樣的映射在一個值中(而不是一個給出全局映射的類型類)。我知道如何手寫(我認爲),但我想知道是否有人已經這樣做了。 –

+1

嘗試從屬地圖包:http://hackage.haskell.org/package/dependent-map –

+0

@NathanHowell:能否請您發佈此作爲答案?我會檢查它,但它從文檔看起來像它是我所要求的。 –

4

首先,全太明顯的答案是,你可以很容易地寫了一個「類型 - >值映射」使用Typeable(基地庫的一部分):

import Data.Typeable 
import Data.Map 

type TypeMap a = Map TypeRep a 

insertT :: Typeable k => k -> a -> Map k a -> Map k a 
insertT v = insert (typeOf k) 

lookupT :: Typeable k => k -> a -> Map k a -> Map k a 
lookupT v = lookup (typeOf k) 

現在你可以使用類似的代碼insertT (undefined :: Int) 5按類型插入元素。

但看融合,這並沒有真正的樣子,你可能是什麼之後。它似乎允許您構建在任意數據結構上工作的代碼?這就是Haskell被稱爲「Scrap your Boilerplate」的泛型編程。有關詳細信息,請參閱papershackage,但它允許您編寫處理任意數據結構並挑選給定類型值的代碼。

我看到的Fusion的其他一些內容可能可以使用庫來模擬,例如HList或可能fclabels。但它真的很難說更多沒有看看你真正需要什麼。

+0

你的'TypeMap'可以工作,但需要一個'unsafeCoerce'來說服編譯器,右邊的類型和左邊的TypeRep(或Data.Dynamic)匹配。 HList看起來也很有趣; fclabels看起來更像它提供的拉鍊。我不需要針對任意數據類型的反射/數據泛型編程,所以我不認爲SYB會有所幫助。 –

+0

那麼,我不確定你是否想要這個值有其索引類型。如果你需要,你可能要麼應該使用'HList'(如果你知道靜態地圖的鍵),或者使用'Dynamic'中的類似地圖構造繞過'unsafeCoerce'。 –

3

如前所述,dependent-map似乎是地圖方面的正確選擇,但我建議查看hlistHArray接口,作爲手動處理元組的替代方案。