2016-05-12 21 views
1

我有一個名爲Showable喜歡這類型:有沒有一種方法來表示函數在GHC的Haskell中顯示的解壓縮?

{-# LANGUAGE ExistentialQuantification #-} 
    {-# LANGUAGE ExplicitForAll #-} 
    data Showable = forall a . Show a => Showable a 

然後使該包裝是微不足道的功能。我只需要寫:

pack :: forall a . Show a => a -> Showable 
    pack x = Showable x 

但是,似乎不可能創建將解包來自Showable的數據的反函數。如果我嘗試只是顛倒了我寫了包,並寫:

unpack :: exists a . Show a => Showable -> a 
    unpack (Showable x) = x 

然後我從GHC的錯誤。

我已經查看了關於GHC語言擴展的文檔,似乎沒有對exists關鍵字的支持。我已經看到在其他一些Haskell編譯器中可能會有這種可能,但我更希望能夠在GHC中做到這一點。

有趣的是,我仍然可以在Showable上模式匹配,並以這種方式從內部提取數據。所以我可以通過這種方式獲得價值,但是如果我想製作一個涉及Showable的免提功能,那麼我需要解包。

那麼有沒有什麼辦法可以在GHC的Haskell中實現解壓縮,也許使用Type家族或者其他一些GHC擴展的神祕魔法?

+0

會是什麼'(解包(包(1 ::智力)))::字符串「是嗎? – Cirdec

+0

我認爲這應該是一個編譯錯誤,因爲你打算在打包這個值之後給它一個類型,因爲在你打包之後你會丟失關於內部錯誤的信息,所以你不知道你是否可以將其類型更改爲String。 –

回答

4

您輸入的unpack不能寫入。原因在於存在變量a「逃避」模式匹配的範圍,並且沒有設施來跟蹤該行爲。報價文檔:

data Baz = forall a. Eq a => Baz1 a a 
     | forall b. Show b => Baz2 b (b -> b) 

當模式匹配,每個圖案匹配引入了一個新的,不同的,類型爲每個存在的類型的變量。這些類型不能與任何其他類型統一,也不能脫離模式匹配的範圍。例如,這些碎片不正確:

f1 (MkFoo a f) = a 

結果類型中的這個「a」是什麼?顯然我們不是這個意思:

f1 :: forall a. Foo -> a -- Wrong! 

原來的程序只是錯誤的。下面是另一個類型的錯誤

f2 (Baz1 a b) (Baz1 p q) = a==q 

這是確定的說a==bp==q,但a==q是錯誤的,因爲它相當於從兩個Baz1構造所產生的兩種截然不同的。

但是,您可以重寫unpack類型等價,這樣的生存確實不逃生

{-# LANGUAGE ExistentialQuantification #-} 
{-# LANGUAGE RankNTypes    #-} 

module Lib where 

data Showable = forall a. Show a => Showable a 

pack :: Show a => a -> Showable 
pack = Showable 

unpack :: Showable -> (forall a. Show a => a -> r) -> r 
unpack (Showable a) a2r = a2r a 
相關問題