これはイドリスで初心者のための混乱の共通の話題です。第conc
バージョンでこの場合 問題:ナットプラス可換性ビューのコンパイラ点から定理であるため
conc : Vect n a -> Vect m a -> Vect (m+n) a
conc [] ys = ys
イドリスは、加算可換性を適用することはできません。タイプ:
Idris> :t plusCommutative
plusCommutative : (left : Nat) -> (right : Nat) -> left + right = right + left
どの定理を適用して適用するかについての一般的な規則はありません。もちろん、いくつかの単純なケース、例えばNat commutativityのようなヒューリスティックを作成することもできます。しかし、これはまた、他のいくつかの場合を理解することを困難にする可能性があります。
あなたが考慮する必要がある他の事はplus
の定義です:
Idris> :printdef plus
plus : Nat -> Nat -> Nat
plus 0 right = right
plus (S left) right = S (plus left right)
パターンは、最初の引数に一致しないされ、このような方法で定義された関数plus
。 Idrisは実際にタイプでこのパターンマッチングを実行できます。だから、最初にあなたがタイプで(0 + m)を持っている
conc : Vect n a -> Vect m a -> Vect (n+m) a
conc [] ys = ys
バージョン、およびイドリスにm
、すべてのtypechecksでplus 0 m
を置き換えることができます。 plus m 0
は、+
演算子を第2引数のパターンマッチングで定義すると機能します。たとえば、これは次のようにコンパイルされます。
しかし、必要な場合に新しい演算子を書くことは恐ろしいことです。だから、第2版をコンパイルできるようにするには、rewrite ... in
の構文をのIdrisに使うべきです。あなたは、次の定理が必要になります。
conc : Vect n a -> Vect m a -> Vect (m + n) a
conc {m} [] ys = rewrite plusZeroRightNeutral m in ys
conc {n=S k} {m} (x :: xs) ys = rewrite (sym $ plusSuccRightSucc m k) in x :: (conc xs ys)
を私はrewriting
と定理証明がここでどのように機能するかをここで説明していないよ:
Idris> :t plusZeroRightNeutral
plusZeroRightNeutral : (left : Nat) -> left + 0 = left
Idris> :t plusSuccRightSucc
plusSuccRightSucc : (left : Nat) -> (right : Nat) -> S (left + right) = left + S right
Idris> :t sym
sym : (left = right) -> right = left
そしてここでは、コンパイルしたバージョンです。あなたが何かを理解していなければ、これは別の質問の話題です。しかし、チュートリアルでそれについて読むことができます(またはThe Book releaseを待つ:)。
偉大なもの - それは本当に明らかです。私は実際には「The Book」の作業を開始しています。MEAPを購入しましたが、今までそれを通過する時間はありませんでした。 – FinnNk