我有以下功能:
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做。
答案 0 :(得分:5)
元组有一个monoid实例:
(Monoid a, Monoid b) => Monoid (a, b)
所以mappend的结果将是:
([1], [2]) `mappend` ([3], [4])
([1, 3], [2, 4])
所以基本上你只需用你的例子中的mappend替换++
答案 1 :(得分: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
答案 2 :(得分: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.