2014-02-12 25 views
0

我是一個相對的Haskell新手,我想創建一個元組列表如下公式我命名爲splits,從單一的列表出現最初,像這樣:創建的元組從列表的變化 - 哈斯克爾

splits [1..4] --> [ ([1],[2,3,4]), ([1,2],[3,4]), ([1,2,3],[4]) ] 

splits "xyz" --> [ ("x","yz"), ("xy","z") ] 

創建可採取1我想通了,我也許應該使用起飛/降功能的元組,然後2,然後3個元素,等的列表,但是這是我到目前爲止,我」 m遇到很多類型聲明錯誤...任何想法?

splits :: (Num a) => [a] -> [([a], [a])] 

splits [] = error "shortList" 

splits [x] 
     | length [x] <= 1 = error "shortList" 
     | otherwise = splits' [x] 1 
     where splits' [x] n = [(take n [x], drop n [x])] + splits' [x] (n+1) 
+0

當你宣佈,第一個參數的類型是一個列表。但是你不需要函數本身的類型,除非你是模式匹配,而只是參數名稱。換句話說,試着用「x」代替「[x]」,我們知道它是一個列表。(「[x]」在這種情況下意味着包含一個元素的列表,x) –

+0

甚至當我嘗試上述時,我得到一個類型錯誤:「無法推論(Num [([a],[a])] )由於使用來自上下文(數字a) 的分割' 的使用而引起的對於 分割:: Num a => [a] - > [([a],[a])] .hs:4:10-39 可能的修正:爲(Num [([a],[a])])添加實例聲明在表達式中:splits'x 1「我不相信我必須定義以這種方式分裂',我也不確定如何。 – user3290526

+0

這個'Could not deduce'錯誤是因爲你試圖把[[把n [x],drop n [x])]'和'splitting'[x](n + 1)'加在一起,沒有任何意義。 –

回答

2

哈斯克爾-Y的方法是使用initstails功能從Data.List

inits [1,2,3,4] = [ [],  [1],  [1,2], [1,2,3], [1,2,3,4] ] 
tails [1,2,3,4] = [ [1,2,3,4], [2,3,4], [3,4], [4],  [] ] 

然後,我們只是壓縮這兩個列表一起落第一對:

splits xs = tail $ zip (inits xs) (tails xs) 

或等同地,首先刪除每個組分列表的第一個元素:

  = zip (tail (inits xs)) (tail (tails xs)) 
1
splits [] = [] 
splits [_] = [] 
splits (x:xs) = ([x], xs) : map (\(ys, zs) -> (x:ys, zs)) (splits xs) 
0

有一個內置的功能樣的,做你想要什麼零件:

splitAt :: Int -> [a] -> ([a], [a]) 

它做什麼它看起來像它會做:

> splitAt 2 [1..4] 
([1,2],[3,4]) 

使用這個功能,你可以像這樣定義分割:

splits xs = map (flip splitAt xs) [1..length xs - 1] 
1

你有幾個錯誤。

您不需要有Num aa

使用[][x]作爲模式,但不是變量,請使用xs代替。

使用++而不是+來連接列表。

在我們的案例中,使用(:)將列表添加到值而不是++

添加停止遞歸,就像附加變量maxnsplits'

splits :: [a] -> [([a], [a])] 
splits [] = error "shortList" 
splits xs 
     | lxs <= 1 = error "shortList" 
     | otherwise = splits' xs 1 lxs 
     where 
      lxs = length xs 
      splits' xs n maxn 
       | n > maxn = [] 
       | otherwise = (take n xs, drop n xs) : splits' xs (n+1) maxn