2

リスト内の反転をカウントするルーチンの 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 バージョンのように動作させる方法に関するアイデアはありますか?

4

2 に答える 2