組み合わせ

前回の改良バージョンを眺めていると組み合わせも簡単に作れることに気付く.
takeOne のときに 前半を捨ててしまえばよさそうだ.


takeOne' :: [a] -> [(a, [a])]
takeOne' [] = []
takeOne' (x:xs) = (x, xs) : takeOne' xs

comb :: Int -> [a] -> a
comb _ [] = [[]]
comb 1 xs = do x <- xs
return [x]
comb n xs = do (x, xs') <- takeOne' xs
guard $ length xs' /= 0
xs'' <- comb (n - 1) xs'
return $ x : xs''

comb のときに長さが足りなくなったら失敗させる (下から3行目)