2017-05-10 30 views
0

我一直在努力與應該返回嵌套元組的功能 - 特別是函數的類型是給了我很多的問題。簡化版本低於:Recusion與元組類型

tupfnc :: ????? 
tupfnc [a] = (a,()) 
tupfnc (a:as) = (a,tupfnc as) 

的想法是採取項目的列表(比如[0,1,5,3])和它們巢到這樣的元組:(0,(1, (5,(3,()))))。

我inital的想法是去同一個聲明,如下所示:

tupfnc :: [a] -> (a,b) 

然而,(本例中的)第三行引發錯誤

Solver.hs:56:17: error: 
    • Couldn't match expected type ‘(a, b)’ 
        with actual type ‘[(a, (a, b0))]’ 
    • In the expression: [(a, tupfnc as)] 
     In an equation for ‘tupfnc’: tupfnc (a : as) = [(a, tupfnc as)] 
    • Relevant bindings include 
     as :: [a] 
     a :: a 
     tupfnc :: [a] -> (a, b) 

有什麼建議?

+3

有幾件事情在這裏下車。首先,你的「數組」(這是一個列表)將總是包含_same_類型。你不能有'[0,1,'a',3]',因爲''''不是'Int'。接下來,你返回一個列表或一個元組,但是它們的類型不同,所以這也是不可能的。最後,但並非最不重要的,其種類'(A,B)'和'(A,(A,B))'不同,除非'b〜(A,B)',因此是無限的。你將不得不使用'數據InPair a = Stop | InPair a(InPair a)'創建它,但現在你又回到了列表中。你在尋找類型級別不一致的列表嗎? – Zeta

+0

寫的問題時,我的壞,我的頭是不是直的。我編輯它是更正確的。該列表的項目都應該是相同的類型。你對b〜(a,b)的評論更多的是我期待的地方。我不知道如何定義一個返回無限類型的函數(就是他們被稱爲?)。我也會看看類型級別不均勻的列表 –

+1

即使編輯,你仍然返回'(a,())'和'[(a,...)]'。你返回一個列表或一個元組,但這些是不同的類型。這似乎是一個XY問題。你究竟想要做什麼? – Zeta

回答

1

,除非您對列表的長度類型級信息這是不可能的。想象叫Vector列出的變體,其中那個地方的話,你可以做到以下幾點:

{-# LANGUAGE GADTs, PolyKinds, DataKinds, TypeFamilies, TypeOperators #-} 

-- | Peano natural numbers 
data Nat = Z | S Nat 

-- Just for convenience... 
type N0 = Z 
type N1 = S N0 
type N2 = S N1 
type N3 = S N2 
type N4 = S N3 
type N5 = S N4 
type N6 = S N5 
type N7 = S N6 
type N8 = S N7 
type N9 = S N8 

-- | Equivalent to a list, but carries information about its length with it 
data Vector (n :: Nat) a where 
    Nil :: Vector Z a 
    (:-) :: a -> Vector n a -> Vector (S n) a 

infixr 5 :- 

現在,我們可以定義一個類型的家庭,一個數字轉換成其相應的嵌套元組:

type family NestedTuple (n :: Nat) (a :: *) where 
    NestedTuple Z  a =() 
    NestedTuple (S n) a = (a, NestedTuple n a) 

最後,我們可以定義轉換Vector n a其嵌套元組形式的功能。

toList :: Vector n a -> NestedTuple n a 
toList Nil =() 
toList (x :- xs) = (x, toList xs) 

您可以在GHCI測試了這一點:

ghci> :set -XFlexibleContexts 
ghci> toList ("foo" :- "bar" :- "baz" :- Nil) 
("foo",("bar",("baz",())))