Haskellの基本を理解するために、Learn YouAHaskellを使用しています。私は関数型プログラミングとパターンマッチングの両方に非常に満足していますが、後者はMathematicaがそれを行う方法にもっと慣れています。
head
4.1章のナイーブな実装と同じ精神で、私は次のようなナイーブな実装を進めましたlast
。
last1 :: [a] -> a
last1 (_:x:[]) = x
ただし、呼び出しlast1 [1,2,3,4]
でエラーが発生しましException: ... Non-exhaustive patterns in function last1
た。このエラーは、指定されたパターンがすべての可能な入力をカバーしていないことを意味し、通常、キャッチオールパターンが必要であることを理解しています(これは提供していません)。ただし、入力に対してこのエラーが発生する理由は正確にはわかりません。
質問1:(私の間違ったアプローチの)私の理解は、最初の要素がによってキャプチャされ_
、残りがに割り当てられるx
ということです。これは、私が意図したものとは正確には異なります。しかし、私が指定したので、これはタイプエラーを与えるべきではありません[a] -> a
が、x
現在はリストになっていますか?
これは動作する関数の書き方ではないことに注意してくださいlast
—私はそれを(他の可能性の中でも)として書くことができることを知っています
last2 :: [a] -> a
last2 [x] = x
last2 (_:x) = last2 x
質問2: Haskellでのパターンマッチングをよりよく理解するという同じテーマに沿って、パターンマッチングを使用して、最後の要素、より一般的にはn
、特定のリストから3番目の要素を選択するにはどうすればよい[1..10]
ですか?
この答えは、拡張子とのパターンマッチングを使用して最後の要素をバインドできることを示唆していますが、のViewPatterns
ような類似の「単純な」パターンがないのは奇妙に思えますhead
数学では、私はおそらくそれを次のように書くでしょう:
Range[10] /. {Repeated[_, {5}], x_, ___} :> x
(* 6 *)
6番目の要素を選択して
Range[10] /. {___, x_} :> x
(* 10 *)
空でないリストの最後の要素を選択します。
これが本文の後半で取り上げられていることをお詫びしますが、それぞれのトピックと概念を、私が知っている他の言語でどのように処理されるかと関連付けて、相違点と類似点を理解できるようにしています。