H99の9問目の回答解説
http://www.haskell.org/haskellwiki/99_questions/Solutions
の9問目。
答え丸写しですが、こういう書き方かっこいいですよね。
まさにHaskell書いてるって感じします。
pack :: (Eq a) => [a] -> [[a]] pack [] = [] pack (x:xs) = (x:first) : pack rest where getReps [] = ([], []) getReps (y:ys) | y==x = let (f,r) = getReps ys in (y:f,r) | otherwise = ([], (y:ys)) (first, rest) = getReps xs
内部で2つ再帰が起こっています。
一つは3行目の部分で、restに対してpackを当てているところ
2つ目はgetReps関数の中でです。
例:[1,1,2]として、ステップ実行をしていってみます。
1. pack (x:xs) = (x:first) : pack rest x:xsは、1と[1,2]に分かれます。 2. firstとrestについて、getRepsにxsを当てた結果なので、 (first, rest) = getReps [1,2] = getReps (1:[2]) = (y==x)なので (f, r) = getReps [2] in (1:f, r) = (otherwise)なので (f, r) = ([], 2:[]) in (1:f, r) = 1:[], 2:[] 3. firstとrestが取れたので、1の右辺に戻す pack (x:xs) = (1:1:[]) : pack 2:[] = (読みやすく) [1,1]: (pack [2]) 4. pack [2]を解く (first, rest) = getReps [] = ([], []) pack 2:[] = (2:first) : pack rest = (2:[]) : pack [] = (2:[]):[] 5. 全部合わせると pack [1,1,2] = [1,1]:[2]:[] = [[1,1],[2]]
できた!すごい!