私の問題はこれを変えることです:
iSort :: Ord a => [a] -> [a]
iSort [] = []
iSort (x:xs) = ins x (iSort xs)
ins x [] = [x]
ins x (y:ys)
| x <= y = x : y : ys
| otherwise = y : ins x ys
比較を行う回数を追跡するソリューションに、ここで生成する必要のあるコードのスケルトンを示します。
iSortCount :: Ord a => [a] -> (Integer, [a])
iSortCount [] = ...
iSortCount (x:xs) = ...
insCount x (k, []) = ...
insCount x (k, (y:ys)) -- Count the times when it reach's here
| x <= y = ...
| otherwise = ...
where ...
私はlets、wheres、writer monadの使用、独自のタイプの作成、state monadから多くのことを試しましたが、「y:ins x ys」の問題に遭遇し続けているため、何かを見過ぎているようです。その関数が返すものは(Int、[a])である必要があり、:はタプルでは機能しないためです。私はそれを分割してこのようなことをしようとしました
do
(a,b) <- ins x (k+1, ys)
return (k, (y : b))
しかし、insがそのバージョンでタプルを返すとは思わないようです。そのため、パターンマッチングが行われていなかったと思います。私の主な質問は、私が今どこを見るべきかということです。私は長い間これに取り組んでいました、そしてこの問題はそれがとても簡単に見えるので私を苛立たせ始めています...
エズラの助けを借りて答える:
iSort' [] = []
iSort' (x:xs) = ins' x (iSort' xs)
ins' x [] = [x]
ins' (x,i) (y:ys)
| x <= fst y = (x,i+1) : y : ys
| otherwise = y : ins' (x,i+1) ys
countInsertions x = sum $ map snd $ iSort' $ zip x $ repeat 0