convs (a:as) bs = convs' [1] [a] as bs
  where convs' _ _ _ [] = []
        convs' ps ars as bs = sumProd3 ps ars bs : 
              case as of
                 [] -> convs'' (next' ps) ars bs
                 a:as -> convs' (next ps) (a:ars) as bs
        convs'' ps ars [_] = []
        convs'' ps ars (_:bs) = sumProd3 ps ars bs : convs'' (next' ps) ars bs
        next xs = 1 : zipWith (+) xs (tail xs) ++ [1] -- next row in Pascal's triangle
        next' xs = zipWith (+) xs (tail xs) ++ [1] -- end part of next row in Pascal's triangle 
        sumProd3 as bs cs = sum (zipWith3 (\x y z -> x*y*z) as bs cs)
convs (a:as) bs = convs' [1] [a] as bs
  where convs' _ _ _ [] = []
        convs' ps ars as bs = sumProd3 ps ars bs : 
              case as of
                 [] -> convs'' (next' ps) ars bs
                 a:as -> convs' (next ps) (a:ars) as bs
        convs'' ps ars [_] = []
        convs'' ps ars (_:bs) = sumProd3 ps ars bs : convs'' (next' ps) ars bs
        next xs = 1 : zipWith (+) xs (tail xs) ++ [1] -- next row in Pascal's triangle
        next' xs = zipWith (+) xs (tail xs) ++ [1] -- end part of next row in Pascal's triangle 
        sumProd3 as bs cs = sum (zipWith3 (\x y z -> x*y*z) as bs cs)
convs (a:as) bs = convs' [1] [a] as bs
  where convs' _ _ _ [] = []
        convs' ps ars as bs = sumProd3 ps ars bs : 
              case as of
                 [] -> convs'' (next' ps) ars bs
                 a:as -> convs' (next ps) (a:ars) as bs
        convs'' ps ars [_] = []
        convs'' ps ars (_:bs) = sumProd3 ps ars bs : convs'' (next' ps) ars bs
        next xs = 1 : zipWith (+) xs (tail xs) ++ [1] -- next row in Pascal's triangle
        next' xs = zipWith (+) xs (tail xs) ++ [1] -- end part of next row in Pascal's triangle 
        sumProd3 as bs cs = sum (zipWith3 (\x y z -> x*y*z) as bs cs)