2011-05-02 31 views
0

我想將列表[[1,2,3],[2,3]]轉換爲元組[[1,2,3],(2,3)]在Haskell中將List的各種長度轉換爲Tuple

我的功能:

thr [a,b,c] = (a,b,c) 
tupel [] = [] 
tupel (x:xs) = if length x==3 then thr x:(tupel xs) else (tupel xs) 

具有三個元素這項工作。

thr [a,b,c] = (a,b,c) 
two [a,b] = (a,b) 
tupel [] = [] 
tupel (x:xs) = if length x==3 then thr x:(tupel xs) else two x:(tupel xs) 

爲什麼不工作呢?

錯誤:在應用類型錯誤 *表達:兩個X:tupel2 XS 期限:兩個X 類型:(A,A) *不符合:(A,A,A )

+0

很確定你需要依賴類型來實現這樣的功能...... – 2011-05-02 18:32:03

+0

相關類型不是必需的。這只是一個普通的舊代數數據類型問題。 – 2011-05-02 18:34:13

+0

@唐嗯,誤解了這個問題。問題是他想要一個異類列表。 – 2011-05-02 18:37:37

回答

4

元組有不同的類型,所以沒有單一(簡單)類型給你的tupel函數。

然而,退一步並使用和類型你可以編碼所有要退回的變體:

data T a 
    = One a 
    | Two a a 
    | Three a a a 
    deriving Show 

two :: [a] -> T a 
two [a,b] = Two a b 

thr :: [a] -> T a 
thr [a,b,c] = Three a b c 

tuple :: [[a]] -> [T a] 
tuple []   = [] 
tuple ([a,b] :xs) = Two a b : tuple xs 
tuple ([a,b,c]:xs) = Three a b c : tuple xs 
tuple (_ : xs)  =    tuple xs 

注意我們的二,三元素列表的情況下區分通過模式匹配。

其次,它是很好的做法寫下來每個函數的預期類型 - 這將有助於在設計解決困惑,並很快顯露象是兩個不同的元組類型的邏輯錯誤。

運行此,你可以看到它是如何組很好的事情:

*Main> tuple [[1,2,3],[2,3]] 
[Three 1 2 3,Two 2 3] 
+0

好的 - 不錯的thx,但我如何轉換[三1 2 3,兩個2 3]到[(1,2,3),(1,2)]? :D – corium 2011-05-02 19:44:15

+5

@corium:這是不可能的:haskell中的列表是同類的(這意味着列表中的每個元素與任何其他元素具有相同的類型),而元素數量不同的元組具有不同的類型。 – ZyX 2011-05-02 19:53:21

+0

這是可能的功能[1,2,3,4,5] - >到[(1,2,3),(4,5)] - 函數獲取列表,但我需要tuple -.- – corium 2011-05-02 20:35:12

6

好吧,讓我們跳過至年底,併火起來ghci的。 [(1,2,3),(1,2)]有什麼類型?

ghci> :t [(1,2,3),(1,2)] 

<interactive>:1:10: 
    Couldn't match expected type `(t0, t1, t2)' 
       with actual type `(t3, t4)' 
    In the expression: (1, 2) 
    In the expression: [(1, 2, 3), (1, 2)] 
    In an equation for `it': it = [(1, 2, 3), (1, 2)] 

該錯誤是不是因爲我輸入的數據錯誤,這是因爲[(1,2,3),(1,2)]是無效的Haskell。

在Haskell名單可以容納物品的數量不受限制,需要提醒的是所有項目必須是同一類型的。

看起來很奇怪,但是(1,2,3)(1,2)不是同一類型。一個是三元組,一個是二元組。

元組是一個列表排序,相反的 - 它只能容納物品的具體數量,但他們可以是一堆不同類型的。元組類型由它們包含的項目給出的類型序列來定義。

所以3點的整數(或如GHC將顯示,像數的東西)的元組是不同的類型的2個整數的元組。我們可以看到,這個直接用:t運營商在ghci的:

ghci> :t (1,2,3) 
(1,2,3) :: (Num t1, Num t2, Num t) => (t, t1, t2) 
ghci> :t (1,2) 
(1,2) :: (Num t1, Num t) => (t, t1) 

請參閱(2,3,4)(2,3)有匹配(1,2,3)(1,2)的分別是類型:

ghci> :t (2,3,4) 
(2,3,4) :: (Num t1, Num t2, Num t) => (t, t1, t2) 
ghci> :t (2,3) 
(2,3) :: (Num t1, Num t) => (t, t1) 

這是因爲(2,3,4)(1,2,3)兩個值具有相同的類型。 (1,2)(2,3)也是如此。

因此,沒有函數在haskell中將[[1,2,3],[1,2]]轉換爲[(1,2,3),(1,2)],因爲這樣的函數的結果不可能進行類型檢查。

相關問題