むドリス蚀語の抂芁

Agdaはあたりにも䞻流です


「先芋性」
画像

 ゜ヌス 



ロシア語のむドリス蚀語に関する資料はほずんどありたせん。簡単な抂芁でこれを修正しようずしたす。 たた、私は、初心者、機胜的ではない、䟝存型のプログラマヌに銎染みのない人にもテキストを理解できるようにしたす。したがっお、そのような蚀語に粟通しおいる人にずっおは、最埌たで巻き戻したり、公匏ドキュメントをすぐに読んだりする方が簡単かもしれたせん。 私は蚀語ず理論の真剣な玹介を曞くこずを想定しおいたせんが、それがすべおであるものを瀺すこずを望みたす。



したがっお、むドリスは、䟝存型を持぀玔粋な関数型汎甚プログラミング蚀語です。



これはなぜですか



簡単な答えずしお、ダむクストラの有名な匕甚が適切です。 それ以来アプロヌチは倉曎されたしたが、目暙は同じたたです。

プログラマの補品は圌らが曞くプログラムだず考えおいる人は、深く間違っおいたす。 プログラマヌは、信頌できる決定を䜜成し、説埗力のある議論の圢でそれらを提瀺する矩務があり、曞かれたプログラムのテキストは、この蚌拠が適甚される資料のみをサポヌトしおいたす。


より正確に蚀うず、䜜成しお䜿甚する理由はいく぀かありたす。著者のEdwin Bradyは、それを䜿甚しお、䟝存型のアプリケヌションプログラミングを研究したす。 私のように、倚くの人が正確なプログラム仕様をコンパむルする機胜が奜きです。 たた、正匏な怜蚌を通じおアプリケヌションプログラムのデバッグ時間を倧幅に短瞮したいず考えおいたす。 そしお、ここで2番目の匕甚が頌みたす

プログラムをテストするず、゚ラヌの存圚を非垞に効果的に実蚌できたすが、゚ラヌがないこずを実蚌するには絶望的に䞍十分です。




静的型付けず䟝存型



プログラミング蚀語のタむピングを分類する方法の1぀は、それを静的ず動的に分けるこずです。 動的型付けでは、型はコンパむル時に䞍明であるため、チェックできたせん。 これはプログラムをより速く曞くのに圹立ちたすが、同時にプログラムの実行䞭に怜出される類型化゚ラヌのクラスを远加したすが、これは通垞あたり快適ではありたせん。 Idrisは静的型付けを䜿甚しおいるため、それに぀いおのみ以䞋で説明したす。 しかし、動的型付けに慣れおいる人を怖がらせないために、 型掚論も䜿甚されおいるこずにすぐに気付きたす。 コンテキストからコンパむラに明らかな型は、明瀺的に省略できたす。



入力は、文字列、数倀、浮動小数点数など、いく぀かのプリミティブ型に制限できたす。 ある倀のタむプたずえば、関数の匕数、たたはそれによっお返される倀に぀いお「蚀う」こずができるのは、 「string」 、 「number」 、 「floating point number」だけです。 しかし、これは通垞、構造のようなもので補完されたす単玔なCのような構造、クラス、䞀般化された代数デヌタ型など、同時に型Cのtypedef



、Haskellのtype



ず同矩で、たずえば「蚀う」こずができたす、 「Date」 、「date」の構造、クラス、たたはタむプを事前に定矩枈み。



これを「ポむンタヌ」ずいうフレヌズで補足できたすが、同時に配列を䜿甚できたすが、高レベル蚀語では、 䞀般的なプログラミング C ++のテンプレヌト、Javaのゞェネリックがより頻繁にサポヌトされ、既に「日付リスト」 、 「道路グラフ」などのフレヌズを䜜成できたす" 、 "むベントツリヌ " 。 ぀たり、型は他の型によっおパラメヌタヌ化できたす。



そしお最埌に、倀で型をパラメヌタヌ化できたす。これにより、 「 5行のリスト」 、 「Vasilyによっお眲名されたメッセヌゞ」 、 関数タむプは、より䞀般的な「メッセヌゞを受信しお​​ナヌザヌデヌタを返す関数 」ではなく、 「特定のナヌザヌによっお眲名されたメッセヌゞを受信し、このナヌザヌのデヌタを返す関数」ずいう圢匏を取るこずができたす 。 さらに、これは、いわば、䞻語から述語ぞの切り替え、「タむプずしおの発蚀」の原則を䜿甚するこずを可胜にしたす 「5は3より倧きい」 、 「5は3より倧きいこずは事実ではありたせん」 、 「7は玠数」 、 「Vasily received 2」メッセヌゞ 。 これらは、偶然、他のいく぀かの蚀語Agda、Coq、EpigramなどでIdrisに実装されおいる䟝存型ですが、Idrisは珟代の応甚蚀語になりたいずいう欲求によっおそれらず区別されたす。



たた、完党な関数型プログラミングの条件䞋では、コンピュヌタヌプログラムず数孊的蚌明の間の察応を䜿甚できたす カレヌ-ハワヌド察応 。たずえば、 「AはB未満、BはC未満、AはC未満」たたは「メッセヌゞが送信されたした」䞀郚のナヌザヌにずっお、これはこのナヌザヌがこのメッセヌゞにアクセスできるこずを意味したす” ; 次に、関数の本䜓が蚌明になりたす。蚌明は、指定された型の倀を返すだけで、蚌明の蚌明は型チェックです。



トヌタル機胜プログラミング



前述のように、むドリスは玔粋な関数型蚀語です。 ただし、関数のtotalityプロパティのオプション芁件もサポヌトされおいたす。これは、2぀のプロパティを意味したす。



  1. 確実性はどこにでもありたす関数は入力に察しお定矩されなければなりたせん。 玔粋な蚀語では、このプロパティが存圚しないこずが、プログラムが「萜ちる」ためのほずんど唯䞀の方法です特にIOの堎合は、そのアクションの䞀郚ず考えられるコンパむラのバグのためにシステムによるプロセスを匷制終了したす。
  2. 厳密な正芏化再垰的な関数呌び出し䞭に、その匕数の少なくずも1぀を厳密に構造的に枛らすか、関数が各反埩で生産的でなければなりたせん-぀たり 結果の䞀郚ず、次の反埩蚈算の玄束を返したす。 前者の堎合、これは停止問題を回避しお機胜の完了を保蚌し、埌者の堎合、有限長で任意の長さの最終プレフィックスを読み取る機胜を保蚌したす。


これは、たず蚌拠を構築するために重芁ですが、私の芳察から刀断するず、通垞のプログラムの正確さは有益です。 ちなみに、このプロパティの存圚により、この関数の遅延蚈算ず貪欲な蚈算の結果が同じになるこずが保蚌され、Idrisの蚈算はデフォルトで貪欲ですが、匕数を遅延させるこずができたす。



このオプションは、個々の関数、ファむル、たたはコンパむラのフラグで有効にできたす。



䟋



異垞な構文は、蚘述されおいる内容の本質から泚意をそらすように思われるため、構文に぀いおは説明したせん。 コヌド䟋はMLファミリヌの蚀語に粟通しおいる人向けに提䟛されおおり、残りの郚分に぀いおは、これらの䟋の前にテキストの説明がありたす。



郹門


ほずんどすべおのプログラミング蚀語たたは暙準ラむブラリで利甚可胜な、誰もが䜿い慣れた操䜜は郚門です。 しかし、0で割るこずは犁止されおおり、さたざたな議論の䜙地がある決定に぀ながりたす。





䟝存型を持぀蚀語、特にIdrisには、別のオプションが衚瀺されたす。0による陀算を犁止したす。蚀い換えるず、0による陀算は犁止されたす。 関数のタむプは、「2぀の数倀を取り、2番目の数倀が0でなく、数倀を返す関数」ず蚘述されたす。 必芁に応じお、戻り倀ず関数の匕数ずの関係を瀺すプロパティでこの仕様を補足できたす。 「...など...」ですが、別の定理に任せる方が簡単ですが、ここでは陀算関数のタむプの説明に戻りたす。通垞の2぀の匕数に、3぀目の匕数を远加する必芁がありたす。



次に、陀算を䜿甚する3぀のケヌスを怜蚎したすコンパむル時間に぀いお話しおいるこずを思い出しおください。



  1. 陀数は既知です。自然数の等䟡性は決定可胜であるため぀たり、コンパむラは陀数がれロかどうかを確認したす、したがっお、必芁に応じお、通垞の2぀の匕数を持぀関数にそのような陀算関数をラップしお、同じ単玔な3番目の匕数。
  2. 陀数は䞍明ですが、れロに等しくないこずを確認するための陀数がわかっおいたす。たずえば、負でない数よりも倧きい堎合です。 次に、蚌拠を所定の堎所に蚘述するか、持っおいるものを取り数が非負数よりも倧きいこずを蚌明する、必芁なものを返す関数を䜿甚するこの数がれロに等しくないこずを蚌明する必芁がありたす。 そのような関数は、単に関数、たたは補題たたは定理ず呌ぶこずができたすが、すでに述べたように、この文脈ではそれはたったく同じです。
  3. 私たち自身は、陀数がれロに等しくないこずを確信しおいたせん䞍平等を蚌明するために状況を慎重に怜蚎した埌、前のケヌスはこのケヌスに入るかもしれたせんこの堎合のみ、実際に陀算の前にチェックを導入する必芁がありたす; 陀数がれロの堎合、代替゜リュヌションを䜿甚し、そうでない堎合は、受信した情報を䜿甚しお陀算を実行したす。




もちろん、このアプロヌチはIdrisでは必芁ありたせんが、プログラマヌが蚈算を正しく実行できるようにしたす。



最埌に、コヌド䟋は陀算関数のフレヌムワヌクです。



 -- (total)      -- "==" -    ,  Bool -- "=" -  ,  total div : (n, m: Nat) -> ((m == Z) = False) -> Nat --   0 - ;     --    , ,      div n Z f = FalseElim $ trueNotFalse f --     div n (S k) f = {-todo-}?div_rhs
      
      







これは単なるワむダヌフレヌムであるため、メタ倉数div_rhs



がここで䜿甚されたす。 Agdaに粟通しおいる人は既に「穎」を知っおおり、その匱いバヌゞョンはIdrisのメタ倉数であり、残りに぀いおは説明したす。Idrisを䜿甚するず、コンテキストその䜍眮から芋える倉数ず目的この䜍眮から構築/返华される、蚌拠ずプログラムの䞡方の蚘述を非垞に容易にしたす。 この堎合、次のようになりたす。



  n : Nat k : Nat f : S k == 0 = False -------------------------------------- div_rhs : Nat
      
      







それらを半自動的に入力するこずも可胜です Nat



を返す目的で、REPL / IDE「refine」コマンドを䜿甚しお、たずえばplus



関数の名前を枡し、 plus



関数が必芁な型の倀を返すこずができる堎合、それを眮き換えたすこのメタ倉数の代わりに、その匕数に2぀の新しいメタが眮き換えられたす。 プロセスは、別の機胜で䜿甚されるプロセスず同じです-メタ倉数の完党自動眮換、぀たり 蚌拠の怜玢堎合によっおは、必芁な蚌拠を自動的に芋぀けるこずができたす。



タむプ読みやすいように少し線集



 λΠ> :t div div : Nat -> (m : Nat) -> (m == 0 = False) -> Nat
      
      





 λΠ> :t div 1 2 div 1 2 : (2 == 0 = False) -> Nat
      
      





 λΠ> :t div 1 2 refl div 1 2 refl : Nat
      
      





 λΠ> :t div 1 0 refl (,        )
      
      







陀算関数の実装から脱線しお、このアプロヌチが私たちに䞎えるものを芋おみたしょう。 前述の正確さから始めたしょう。関数は本来の動䜜をしたす。 関数は、通垞、実装するものず考えお考えるこずができたす算術、この堎合れロで陀算するこずはできたせんが、陀算の過皋で䟋倖のような抂念は含たれず、結果は数倀です。 関数に぀いおは、圢匏的にも含めお、それが衚す抂念ず同じ方法で話すこずができたす。 掚論をコヌドで曞き留めたす。 これを䜿甚する関数では、掚論ず結論が蚈算ず絡み合っおチェックできるようになり、プログラマヌの頭の䞭やテキストコメントに残るこずはなくなりたした。 たた、プログラムは、蚈算のレシピだけでなく、正しい掚論ず決定から構成されたす。



リスト


リストたたは配列を操䜜するこずも、ほが同じ䞀連の物議を醞す決定ずその埌の゚ラヌに぀ながる䞀般的なタスクです。 特に、リストのn番目の芁玠を返す関数を考えたす。その実装の問題は、リストにない䜍眮から芁玠を芁求できるこずです。 通垞の解決策は、「アクセス違反」たたは「セグメンテヌションフォヌルト」に該圓し、䟋倖をスロヌする堎合によっおはそれで該圓する堎合がありたす。



䟝存型を持぀蚀語では、さらに考えられる解決策がいく぀か珟れたす。 最初の方法は、れロによる陀算の問題を解決するのず䌌おいたす。 関数の最埌の匕数は、芁求された䜍眮がリストの長さより小さいこずの蚌明です。



ここでは、さたざたな数字、リスト、「if-then-else」などを確認できたす。 蚀語自䜓で定矩されおいたす。 ラむブラリに実装されおいる自然数は、Cでのコンパむル時にGMP番号に眮き換えられ、加算や乗算などの関数は察応するGMP関数に眮き換えられたす。これにより、コンパむルされたプログラムでの迅速な蚈算ずそれらに぀いおの話し合いが可胜になりたす。 次に、コヌドを芋おみたしょう。



 data Nat = Z | S Nat data List a = Nil | (::) a (List a) length : List a -> Nat length [] = 0 length (x::xs) = 1 + length xs index : (n : Nat) -> (l : List a) -> (ok : lt n (length l) = True) -> a index Z (x::xs) p = x index (S n) (x::xs) p = index n xs ?indexTailProof index _ [] refl impossible indexTailProof = proof { intros; rewrite sym p; trivial; }
      
      







indexTailProof



はCoqスタむルの戊術を䜿甚した蚌明ですが、Agdaスタむル、぀たり より銎染みのある機胜真実は、戊術がたもなくAgdaにも導入されるずいうこずです。



2番目の解決策は、リストだけでなく、固定長のリスト、぀たり、䟝存型を持぀蚀語のコンテキストで呌び出されるベクタヌを䜿甚するこずです。 䞊蚘で䟋を挙げたした。これにより、「5行のリスト」ず蚀うこずができたす。 いわゆる 最終型-぀たり、異なる倀の数が有限である型自然数の同じ型であるが、䞊限があるず考えるこずができたす。 このタむプは、自然数よりも「n未満の数」ず蚀う方が簡単であるため、特に䟿利です。 ベクトルのn番目の芁玠を取埗するための関数の型は、「n未満の数ずn型の芁玠のリストを取り、a型の芁玠を返す関数」ずしお読み取られたす。



この堎合、タスクは蚌明を提䟛するこずではなく、必芁なタむプn未満を構築するこずです。 ちなみに、ここでの蚌明の論理は叀兞的盎芳的ずは異なり、蚌明の構築にありたす。぀たり、ステヌトメント/型の蚌明はこの型の任意の倀であるため、以前のアプロヌチずの類䌌性を远跡できたすが、同時に、プログラム党䜓を曞くず、それは倉わりたす。



コヌド



 data Fin : (n : Nat) -> Type where fZ : Fin (S k) fS : Fin k -> Fin (S k) data Vect : Nat -> Type -> Type where Nil : Vect Z a (::) : (x : a) -> (xs : Vect na) -> Vect (S n) a index : Fin n -> Vect na -> a index fZ (x::xs) = x index (fS k) (x::xs) = index k xs --  -    ,    --   ""  index fZ [] impossible
      
      







したがっお、明確な蚌拠からさらに先に進みたすが、正しいプログラムを構築しおいたす。



さお、ベクトルにたどり着いたので、ここにそれらを結合する機胜がありたす。倚くの堎合、䟝存型を瀺すための䟋ずしお䞎えられおいたす。



 (++) : Vect ma -> Vect na -> Vect (m + n) a (++) [] ys = ys (++) (x::xs) ys = x :: xs ++ ys
      
      







本文は通垞のリストず同じですが、タむプはより興味深いものですm + n



泚意しおください。



その他の䟋



䞊蚘は、むドリスが修正するのに圹立぀個々の小さな関数の䟋ですが、ここにいく぀かのより倧きなものがありたす







DOMずやり取りするためのWebフレヌムワヌクずラむブラリの䞡方がその䞊に蚘述されおおり執筆時点では、コンパむラはC、LLVM、Java、およびJavaScriptでのコンパむルをサポヌトしおいたす、あらゆる皮類のパヌサヌ one 、 two であり、システムプログラミングを察象ずしおいたす。 HaskellからIdrisに察応するプログラムは非垞に簡単です。



むドリスはただ生産に䜿甚されおいたせん-少なくずも広く䜿われおいたすポツダム気候圱響研究所で積極的に䜿甚されおいるず聞きたしたが、これは通垞生産で正確に理解されおいるずは限りたせん。 䞻な技術的障害は「非ロヌルむン」であり、これは「ロヌルむン」によっお決定されるべきです。



おわりに



この蚀語は新しいため、「未加工」ですが、他の蚀語で蓄積された珟代の理論ず実践を䜿甚しお珟代的です。



むドリスおよびその埌に登堎する蚀語の将来の䜿甚に぀いお少し倢を芋るこずができるようになるず、プログラムの信頌性の䞀般的な向䞊に加えお、正匏な仕様に䌎う技術的なタスク、たたはそれらからなるこずさえ想像できたす。 プルヌフマヌケットのようなサヌビスの成長。 物理、数孊、ロゞバンのような他の理論ず蚀語のラむブラリ。 蚌明された定理の正匏な仕様のリストずしおの蚘事ず本。 特に自動的にチェックされたレプリカず質問ず回答のペアから構築された通信。



関連リンクず本







PS



コメントずアむデアに぀いお、このレビュヌがテストされた人々に感謝したす。



All Articles