2013-10-30 17 views
1

遞歸返回一個元組,我有以下功能:如何在Haskell

function :: [String] -> [[Int]] -> ([[Int]],[[Int]]) 

我想知道是否有可能做這樣的事情:

function :: [String] -> [[Int]] -> ([[Int]],[[Int]]) 
function a (b:bs) = if condition then ([[]], [b]) ++ function a bs else 
([b], [[]]) ++ function a bs 

當然,我中可以編寫兩個返回每個[[Int]]的函數,但我希望以更合適的方式爲Haskell完成。

回答

3

有關使用map如何?

import Data.Monoid 
f :: t -> [a] -> ([a], [a]) 
f a = mconcat . map part 
    where part b = if True then ([], [b]) else ([b], []) 

所以我們讓part選擇哪列出我們的b元素會去,讓`map,並mconcat壓扁了。

它是慣用的haskell,以避免顯式遞歸,所以雖然你可以通過mappend代替++來修復你的代碼,因爲你要求更合適的haskell方式,我會建議你這樣做。

哦也,你可以只使用break

f s = break $ \b -> condition 
+0

這對我很好。只有一個我不明白的錯誤。我的輸出包含許多[]。我認爲[]不會被添加到最終輸出中。 – user2925688

+0

所以用([],b)我的意思是,第一個或第二個值是空的。 – user2925688

+0

@ user2925688現在應該修復 – jozefg

2

最Haskellic的方式很可能是使用unzip(?):

function a bs = unzip $ function' a bs 
    where function' a (b:bs) = (if condition then ([], b) else (b, [])) : function' a bs 
      function' _ [] = [] -- You forgot the base case. 
5

有一個元組幺實例:

(Monoid a, Monoid b) => Monoid (a, b) 

所以mappend的結果將是:

([1], [2]) `mappend` ([3], [4]) 
([1, 3], [2, 4]) 

所以基本上你只需在示例

中用mappend替換
+1

最好只寫'([1],[2])<>([3],[4])''。 – leftaroundabout

+0

請注意,元組的mappend不是懶惰的,所以對於長列表的當前用例來說這可能是一個壞主意。 –