むずかしめのパソコン勉強の記録

計算機科学とか関数型言語とか

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]]


できた!すごい!