第2回スタートHaskellの演習問題のsplitAtは自力で解けたのに、第3回スタートHaskellの演習問題では解けず時間切れになってくやしかったので、考えをメモりながら考えた。
ざくっと戦略はこう:
- 基底部はこの形になるはず: splitAt 0 xs = ([],xs)
- 再帰部は、タプルの1stを (:) でつくりつつ2ndはいじらない。
引数とおなじリストをつくる(リストコピー)はこの形↓なので、再帰部も同じ形になるはず。
copy [] = [] copy (x:xs) = x : copy xs
splitAtではタプルを返さないといけないから変形が必要で、「ひとつまえがあったら...」の考え方で、「splitAt n (x:xs)」は「(ys,zs) = splitAt (n-1) xs」をもとに「(x:ys, zs)」を返せばいいはず。
splitAt :: Int -> [a] -> ([a], [a]) splitAt n xs | n <= 0 = ([], xs) splitAt _ [] = ([], []) splitAt n (x:xs) = (x:ys, zs) where (ys, zs) = splitAt (n-1) xs
let式をつかうとこんなかんじ:
splitAt n (x:xs) | n > 0 = let (ys, zs) = splitAt (n-1) xs in (x:ys, zs) | otherwise = ([], (x:xs)) splitAt n [] = ([], [])
なんとか解けたので、ぐっすり寝れそうだ。