リスト内の反転をカウントするルーチンの Haskell 実装からの関連コードを次に示します。
mergeAndCount :: Ord a => [a] -> [a] -> (Int,[a])
mergeAndCount l@(x:xs) r@(y:ys) | x < y = let (inv, s) = mergeAndCount xs r in (inv, x:s)
| otherwise = let (inv, s) = mergeAndCount l ys in (inv + rest, y:s)
where rest = length l
mergeAndCount l [] = (0, l)
mergeAndCount [] r = (0, r)
Scala で同様のルーチンを作成しようとしましたが、スタック オーバーフローでクラッシュします (ただし、遅延ソートは機能します)。非動作バージョンは次のとおりです。
def mergeAndCount(l: Stream[Int], r: Stream[Int]) : (Long, Stream[Int]) = {
(l, r) match {
case (x#::xs, Empty) => (0, l)
case (Empty, y#::ys) => (0, r)
case (x#::xs, y#::ys) => if(x < y) {
lazy val (i, s) = mergeAndCount(xs, r)
(i, x#::s)
} else {
lazy val (i, s) = mergeAndCount(l, ys)
(i + l.length, y#::s)
}
}
}
Scala バージョンを Haskell バージョンのように動作させる方法に関するアイデアはありますか?