Моя проблема состоит в том, чтобы превратить это:
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 ...
Я много чего пробовал, используя let, wheres, writad monad, создавая свой собственный тип, монаду состояния, и я, кажется, просто перебрал что-то, потому что продолжаю сталкиваться с проблемой с "y: ins x ys "потому что то, что возвращает эта функция, должно быть (Int, [a]) и: не работает с кортежем.Я пытался разделить его, чтобы сделать что-то вроде этого
do
(a,b) <- ins x (k+1, ys)
return (k, (y : b))
, но, похоже, он не думает, что ins возвращает кортеж, когда он это делал в той версии, так что, я думаю, это не было совпадением с шаблоном.Мой главный вопрос: где мне сейчас искать?Я работал над этим долгое время, и эта проблема начинает меня расстраивать, потому что это выглядит так просто ...
Ответ с помощью Ezra:
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