パターンマッチングによってリストの先頭と末尾をバインドする方法があるので、パターンマッチングを使用してリストの最後の要素をバインドできるかどうかは疑問です。パターンマッチングを使用してリストの最後の要素をバインドできますか?
答えて
はい、ViewPatterns
拡張子を使用できます。
Prelude> :set -XViewPatterns
Prelude> let f (last -> x) = x*2
Prelude> f [1, 2, 3]
6
このパターンはいつもあなたは、おそらくリストが空である場合のパターンを追加したいと思うので、他のlast
は、例外がスローされます、しかし、成功することに注意してください。
Prelude> f []
*** Exception: Prelude.last: empty list
これは単なる構文的な砂糖です。通常のパターンマッチングとは異なり、これはO(n)です。これは、依然として単一リンクリストの最後の要素にアクセスしているためです。より効率的なアクセスが必要な場合は、Data.Sequence
などの異なるデータ構造を使用することを検討してください。O(1)の両端にアクセスできます。
あなたは
printLast :: Show a => IO()
printLast (reverse -> (x:_)) = print x
printLast _ = putStrLn "Sorry, there wasn't a last element to print."
例えば、リストの最後にパターンマッチングを行うために
ViewPatterns
を使用して、それでは
{-# LANGUAGE ViewPatterns #-}
を行うと、それは常に成功しているため、viewFunctionとしてreverse
を使用してみましょう、そうすることができます
これは、すべての可能性をカバーする限り、例外をスローしないという意味では安全です。あなただけの、実際にそれを見ることができるように (あなたがたとえば、Maybe
を返すように書き換えることができます。)
構文
mainFunction (viewFunction -> pattern) = resultExpression
は
mainFunction x = case viewFunction x of pattern -> resultExpression
ためのシンタックスシュガーでありますリストを逆にしてパターンをマッチさせますが、それはより良い感じです。 viewFunction
は、好きな機能に過ぎません。 (延長の目的の一つは、彼らが がそれに関数を定義するときにそのデータ型の基本構造を使用する必要はありませんでしたので、人々はきれいにし、簡単にパターンマッチングのためのアクセサ関数 を使用できるようにすることでした。)
その他の回答は、ViewPatterns
ベースのソリューションについて説明しています。
tailLast :: [a] -> Maybe ([a], a)
tailLast [email protected](_:_) = Just (init xs, last xs)
tailLast _ = Nothing
pattern Split x1 xs xn = x1 : (tailLast -> Just (xs, xn))
をして、例えばとしてあなたの関数を書く:あなたはそれがより多くのパターンマッチングのようにしたい場合は、PatternSynonym
にそれをパッケージ化することができます
foo :: [a] -> (a, [a], a)
foo (Split head mid last) = (head, mid, last)
foo _ = error "foo: empty list"
これはHaskellのプログラミングの私の最初の日であり、私も同じ問題に遭遇しましたが、私は、以前のソリューションで示唆されているように、外部アーティファクトのいくつかの種類を使用することを解決できませんでした。
ハスケルについての私の気持ちは、コア言語があなたの問題の解決策を持たないならば、その解決策は言語のために働くまであなたの問題を変えることです。
この場合、問題を変換するということは、テールの問題を頭の問題に変換することを意味します。これはパターンマッチングで唯一サポートされているようです。リスト逆変換を使って簡単に行うことができ、元のリストのtail要素を使用するようにhead要素を使用して逆のリストを処理し、最後に結果を元の順序に戻すことができます(ifそれはリストでした)。
たとえば、整数のリスト(たとえば[1,2,3,4,5,6])が与えられた場合、このリストを作成して、元のリストの最後から2番目の要素その二重に置き換えられます(Homework1からthis excellent introduction to Haskellの運動):[2,2,6,4,10,6]。
その後、我々は次のように使用することができます。
revert :: [Integer] -> [Integer]
revert [] = []
revert (x:[]) = [x]
revert (x:xs) = (revert xs) ++ [x]
doubleSecond :: [Integer] -> [Integer]
doubleSecond [] = []
doubleSecond (x:[]) = [x]
doubleSecond (x:y:xs) = (x:2*y : (doubleSecond xs))
doubleBeforeLast :: [Integer] -> [Integer]
doubleBeforeLast l = (revert (doubleSecond (revert l)))
main = putStrLn (show (doubleBeforeLast [1,2,3,4,5,6,7,8,9]))
それははるかに長く、以前のソリューションよりも明らかだが、それは私に多くのハスケルっぽいを感じています。
ようこそStackOverflowへようこそ、このような良いスタートをお祝い!遠端にアクセスするためにリストを逆転させることは実際には非常に効率的です(しかし、それはむしろ非効率ですが、 'last'を使うことは、何度もやり直す必要がある場合にはさらに悪化する可能性があります。最後の要素なら、リストは適切な型ではありません)。おかげさまで – leftaroundabout
ありがとうございます。私のルーキーレベルでは、実際にパフォーマンスの影響を調べるよりも、ハスケルプログラミングのイディオムを発見することにもっと興味があります。私は逆の順序で単純リンクリストを使用しようとすると間違いなく悪いケースであると私は同意します、そして、これは実際にハスケルが最初にテールパターンマッチングを提供しない理由だと思います。 (ハスケルリストは、単純リンクリストを使って実装されています。) – OlivierD
正しい。 Haskellのリストはスタックとして、または無限ストリームとして素晴らしいですが、ランダムアクセスでは本当に悪いですし、遠端にアクセスすることは途中の任意の要素にアクセスすることより優れていません。 – leftaroundabout
- 1. リストの最後の要素を見つけるためのパターンマッチング
- 2. パターンマッチングを使用してリスト内の要素のペアを交換する
- 3. リストの最初と最後の要素を返します。
- 4. pythonのリストの最後に要素を挿入しますか?
- 5. anglejsのリストから最後の要素を削除します
- 6. フレックスボックスを使用して1つの要素をリストの最後に移動
- 7. findelementをネストした後も要素のリストは最初の要素を使用し続けます
- 8. SASSは最後の要素から最後の要素を選択します
- 9. Scalaを使用してリストの最初の要素を印刷
- 10. リストの最後の要素として要素を挿入する
- 11. Sharepointリストの最後のx要素を表示します
- 12. Haskellのリストの最後に要素を追加します。
- 13. XElementを使用してC#の最後の要素を取得
- 14. Prolog:最後の要素をピボットとして使用するquicksort
- 15. Hibernate - ScrollMode.FORWARD_ONLYを使用してScrollableResultsの最後の要素を取得します。
- 16. iScroll 4を使用して最後の要素をスクロールして最初の要素の開始位置にスクロール
- 17. ループ内のリストの最後の要素
- 18. リストの最後から最後の2つの要素を取得できません。C++、mfc
- 19. Popリストの最後の要素Scala
- 20. ディレクティブを使用して、要素の最後にメッセージを挿入します。 Angular.JS
- 21. 再帰を使ってhaskellのリストの最後の要素を返す
- 22. C++リストの最後まで消去するリスト(リスト内の1つの要素)
- 23. リストから最後の要素のみを取得する
- 24. Scalaリストの最後から2番目の要素を探す
- 25. R:リスト内の各要素の最後のサブ要素にアクセス
- 26. 角度ファイア2:FirebaseListObservableリストの最後の要素を取得しています。
- 27. クイックソートで最後の要素をピボットとして返します
- 28. Javaでリスト要素の最後の部分を取得する
- 29. selenium pythonを使用してspanの文から最後の要素を取得
- 30. UpdateItemを使用してリストから要素を削除できません
最後に空のリストで例外がスローされます。私は最後から頭を離れることを目指しています、頭、fst、snd。空リストをうまく扱えない関数。パターンマッチング、let(x:xs)= "abcdefg"などは、私の質問で言及したものです。安全でないプレリュード関数を使用せずに、最後の要素を得るための同様のアプローチが必要であると考えていました。 –
@MichaelLitchard:まあ、あなたは 'Maybe'を返す' safeLast'関数を定義することができます。この関数はパターンマッチやリストを逆順にして通常のパターンマッチングを使うことができます。 – hammar
それは常に成功するので、「パターンマッチ」はあまりありません。 'f =(* 2)。最後は良いです。 – u0b34a0f6ae