2016-12-22 2 views
1

ガードでのパターンマッチングの使い方を理解できません。Haskell - Pattern Matchingフォーム(x:y:zs)

このサンプル関数は、文字列の最後の文字を返すことを目的としています。

myFun :: [Char] -> Char 
myFun [email protected](f:s:rst) 
     | str == "" = error "0 length string" 
     | length str == 1 = head str 
     | rst == "" = s 
     | otherwise = lame (s:rst) 

1文字の文字列が渡されたときに「関数内の非網羅的なパターン」で失敗しています。

Haskellは、(f:s:rst)という形式を使用して1つの要素リストに一致することができないと認識してから、lengthへの呼び出しを評価しようとすると失敗します。

ハスケルに要素が1つしかない場合の対処方法を教えてくれるガードを作成するにはどうすればよいですか?

答えて

4

機能定義レベルでパターンマッチングしています。あなたはそれを説明している方法は、あなただけの文字列が2文字以上である場合をカバーしています

myFun [email protected](f:s:rst) 

あなたは同様に他のケースを処理する必要があります。前キャッチオールへ

myFun _ = ... 

それとも、処理したい場合、例えば、このような空の文字列、(:あなたは、このようなキャッチオールハンドラを(最後のパターンとして行く必要)を持つことができ):

myFun [] = ... 

機能の目的に関しては、パターンマッチングを使用し、ガードを使用しない方がよいでしょう。

myFun :: [Char] -> Char 
myFun [] = error "empty string" 
myFun [x] = x 
myFun (x:xs) = myFun xs 

私は方法を発見したチャド・ギルバート、およびいくつかの追加の工夫、 から特に役立つの回答に基づいて

+0

これは機能します - 現実的に、これを行うためのさまざまな簡単な方法があります。 私がここで本当に苦労しているのは、引数が提供されたパターンで解体できない場合に、何をすべきかを警備員に伝える方法があるかどうかを調べることです。 私はあなたの応答を意味する必要があります: "はい、ガードを使用するときは不可能な、関数宣言でパターンを定義する" –

+2

ファンクションレベルのパターンマッチングが最初に行われます。つまり、最初の2つのガードあなたが遭遇する可能性のある条件(ゼロまたは1つの長さの 'str'をチェックするもの) –

1

(あなたのプログラムをクラッシュするのではなく、Maybe Charを返すために、より慣用的になることに注意してください)私のケーキを食べて食べること。

strSplit :: [Char] -> [[Char]] -> [[Char]] 
strSplit str [] = strSplit str [""] 
strSplit "" _ = [""] 
strSplit [email protected](s1:ns) [email protected](x:xs) 
     | s1 == '|' = strSplit ns ("":list) 
     | ns == "" = map reverse $ ((s1 : x) : xs) 
     | otherwise = strSplit ns ((s1 : x) : xs) 

またはスタッフが使用して:これは、複数の引数で動作します

myFun :: [Char] -> Char 
myFun "" = "" 
myFun [email protected](s:rst) 
     | rst == "" = s 
     | otherwise = myFun (s:rst) 

:誰もが同様のつまずきを持っている場合は は、ここにあなたの警備員を宣言する前に覆われていないケースを指定する方法であります元[email protected](first:second:rest)アイデア:

lastTwo :: [Char]->[Char] 
    lastTwo "" = "" 
    lastTwo [x] = [x] 
    lastTwo [email protected](f:s:rst) 
      | rst =="" = [f,s] 
      | otherwise = lastTwo (s:rst) 

これはおそらくHaskellのに慣れて人々にスーパーは明白ですが、私はそれを実現しませんでしたさまざまなケースをカバーするために異なる構文を使用して関数を複数回宣言するだけで "許可"されました。

+0

楽しいために、あなたは次のようにすることもできます:' lastTwo = reverse。 2を取る。逆。 –