2012-05-11 113 views
3

比方說,我有一個函數,它的功能列表對的列表,並映射函數中的每一對到列表中的一對,例如:如何在不使用混合列表的情況下實現此功能?

myFunction [("SOME"++,["DAY","ONE"]), (show,[1,2])] == [["SOMEDAY", "SOMEONE"],["1","2"]] 

是否有執行myFunction的這樣的一種方式我上面提供的代碼將按原樣工作,不作任何修改?

我的問題是我無法弄清楚如何實現myFunction,因爲每個子列表的類型可能不同(在我的例子中,我有一個字符串列表[「DAY」,ONE「]和列表我知道列表中的每個函數都會將它的列表轉換爲一個字符串列表(所以最終列表將有類型[[Char]]),但我不知道如何哈斯克爾表示這種

+3

你不能「按原樣」,因爲參數列表本身已經不會進行類型檢查。最接近的答案是使用存在類型。但在95%的案例中出現這個問題,這實際上是挑選錯誤設計的一個症狀。所以讓我問一下,你爲什麼要*做這個? –

+0

對於「原樣」,我可能應該更清楚地表達自己,我只是想避免諸如「創建數據類型A = Int | String並將其用作包裝器」這樣的解決方案,應該有最接近的答案。 –

+0

至於我想做什麼,一個更接近我的真實代碼的例子如下。我有一個函數openURLs,它需要一個url列表。我也有兩個列表l1 = [「google」,「wikipedia」],l2 = [(「google」,「zebras」),(「wikipedia」,「tigers」)],我也有函數f1和f2,f1這將把與l1類型相同的列表轉換爲URL列表,f2用於列表類型爲l2的列表。 –

回答

4

您可以用存在主義類型

{-# LANGUAGE ExistentialQuantification #-} 

data T = forall a b. Show b => (:?:) (a -> b) [a] 

table = 
    [ ("SOME"++) :?: ["DAY","ONE"] 
    , (show)  :?: [1,2] 
    , (+1)  :?: [2.9, pi] 
    ] 

做並運行它爲:

apply :: T -> String 
apply (f :?: xs) = show $ map f xs 

main = print $ map apply table 
1

想要使用存在性量化來定義一個類型,只要它是類型類型Show的成員就可以保存任何值。例如:

{-# LANGUAGE ExistentialQuantification #-} 

data S = forall a. Show a => S a 

instance Show S where 
    show (S s) = show s 

f :: [S] -> [String] 
f xs = map show xs 

現在在ghci的:

*Main> f [S 1, S True, S 'c'] 
["1","True","'c'"] 

您將無法在不修改你的問題運行的代碼,因爲它包含一個異類名單,Haskell的類型系統禁止。相反,您可以將異構類型作爲變體類型包裝(如果您事先知道所有需要的類型)或作爲存在量化類型(如果您不知道需要什麼類型,但您確實知道某個屬性他們必須滿足)。

相關問題