2012-09-30 5 views
5

私はいくつかの一般的なアルゴリズムを実装しているスケーラをぶち壊しています。私はこの問題このNilケースを省略するにはどうすればいいですか?

に走ったバブルソートを再作成しようとしたときにここでトップに値を泡内部ループの実装です:

def pass(xs:List[Int]):List[Int] = xs match { 
    case Nil => Nil 
    case x::Nil => x::Nil 
    case l::r::xs if(l>r) => r::pass(l::xs) 
    case l::r::xs => l::pass(r::xs) 
} 

私の問題は、ケースNil => Nilです。私はこの機能にNilを適用できるので、これが必要であると私は理解しています。 Nilがコンパイラを満たす方法で引数として提供されないようにする方法がありますので、このケースを排除できますか?

答えて

4

リストには2つのサブタイプNilと::があります。したがって、::は少なくとも1つの要素を持つリストを表します。

あなたは、単に case句で遊ぶことができ、その場合には
def pass(xs: ::[Int]):List[Int] = xs match { 
    case x::Nil => x::Nil 
    case l::r::xs if(l>r) => r::pass(new ::(l,xs)) 
    case l::r::xs => l::pass(new ::(r, xs)) 
} 
+1

ああ、よく分かりませんでしたが、スカラについてはわかりません:-) –

+1

これは一般的に 'List [Int]'の値にこの関数を適用することができないことに注意してください。実行時に指定された 'List [Int]'が空であるかどうかを認識していません(そうすることで、Haltingの問題を解決する必要があります)。パターンマッチングは、一般的に知られていない 'List [Int] '値が、' Nil'か ':: [Int]'かによって2つの異なる枝に分かれる仕組みです。これは、リストを 'List [Int]'として渡している場合、 'pass'を呼び出すたびにそれらのパターンを一致させる必要があることを意味します。 – Ben

+0

そして、 'pass(1 :: 2 :: Nil)'のように呼び出すことはできません... –

2

これは、元のタイプの洗練されたにおおよそ対応します。ここでは、メンバが初期タイプのサブセットであるタイプを記述します。その場合、関数への入力がすべてxの場合、そのxNilではないことを示します。これには十分な証明が必要です(サブタイプタイプを使用して従属タイプのCoqでこれを実装できます)。この場合、より良いことは、Nilのコンストラクタを持たないリストである新しいタイプを導入することです、コンスのコンストラクタと単一の要素のみです。

編集:Scalaでは、List型のサブタイプを使用してこれを強制することができるため、そのサブタイプを使用して型システムでそれを証明できます。これはまだです。つまり、プログラムが実際に何らかの型に存在しているという証拠には、コンパイラが完全に証明できるものです。

+0

なぜdownvote?私はこの答えに何か間違っているとは思わない?あなたはそれに技術的に間違っていることを指摘できますか?もしそうなら、私はそれを変更または削除します。 –

+0

あなたは何か複雑な証明に頼らずにKim Stebelによって提案されたトリックを使うことができるので... – paradigmatic

+0

@paradigmatic間違っていますが、それはまだ型システムの証明に対応しています、証明はサブタイプによる証明です、それは決定的な論理に過ぎません。それでも証拠はありますが、私は自分の答えを編集しました。 –

2

注文:

def pass(xs:List[Int]):List[Int] = xs match { 
    case l::r::xs if(l>r) => r::pass(l::xs) 
    case l::r::xs => l::pass(r::xs) 
    case xs => xs 
} 

最初の2つの句は、1つのまたは複数の要素をリストに一致します。最後の節は他の部分と一致します。

+1

これはNilが渡されるのをどのように排除しているのでしょうか?コンパイラはまだNilを渡すことを強制できません。引数は並べ替えを指定します。 –

+0

それはそれを排除するものではありませんが、質問のタイトルに記載されているように、 "Nilの場合を除外"することができます。 – paradigmatic

+1

おそらくタイトルに同意しますが、OPが「コンパイラを満足させるようにNilを引数として提供できないようにして、このケースを排除できる」という声明に同意しません。 –

関連する問題