2017-11-25 3 views
-3

パターンマッチングを使って定義されたHaskell関数を取得しましたが、なぜそれが正しいかはわかりません。safeTail関数のHaskellパターンマッチング

safeTail (x : xs) = xs 

私は本当に(x:xs)を理解できません。どういう意味ですか?

+0

ます:

safeTailの完全な定義はまた、空のリスト引数の値を提供します'unsafeTail'や' dangerousTail'という名前を付けました。これは空のリストでクラッシュするためです。 – chi

+0

私は空リストのキャッチオールを得ましたが、ここではそれを置かないことにしました。ここでの主なポイントは、関数ではなく(x:xs)の構文を理解できないからです。 – Wandy

答えて

1

パターンマッチングです。

ファンクションsafeTailの最初の引数はリスト型の1つです。引数が空でないリストの場合、このパターンマッチングは成功し、xをhead要素にバインドし、xsをリストの末尾にバインドします。

空リストをsafeTailに渡す場合、パターンの一致は失敗し、他のパターン(存在する場合)がチェックされます。

2

リストデータ型についても同様の定義を考えてみます。

data List a = Empty | Cons a (List a) -- (1) 

空のリストを作成するコンストラクタと、値と別のリストが与えられたリストを作成するコンストラクタの2つのコンストラクタがあります。

パターンマッチングは、作成に使用したコンストラクタと値をマッチングさせることで機能します。 safeTailConsコンストラクタを使用して定義された値に適用された場合である

safeTail (Cons x xs) = xs -- (2) 

は、戻り値はConsに二番目の引数です。実際のコードで

、型コンストラクタListEmptyデータコンストラクタの両方が[]命名され、Consコンストラクタは(:)という名前です。

Haskellは型または型変数に型建設業者 []を適用する特別な構文で

data [a] = [] | a : [a] 

を書き込むことができるが、[]内部引数、及びシンボリックコンストラクタ(などで置換することができる

data [] a = [] | (:) a ([] a) 

:で始まるため)を中置演算子として使用できます。

ある

、次のように書くことができ

safeTail ((:) x xs) = xs -- (3) 

又は有する

safeTail (x : xs) = xs -- (4) 

(2)、(3)、(4)と等価である上記(1)。さらに簡単にするため

>>> safeTail ((:) 3 ((:) 2 ((:) 1 []))) 
[2,1] 
>>> safeTail (3:2:1:[]) 
[2,1] 
>>> safeTail [3,2,1] 
[2,1] 

は、Haskellは、等[x,y]、として(x:y:[])[x]として(x:[])表しますそれは、関数の完全な定義だ場合、私は、

safeTail [] = [] 

またはMaybeベースの定義

safeTail :: [a] -> Maybe [a] 
safeTail [] = Nothing 
safeTail (x:xs) = Just xs 
+0

'Maybe'ベースの定義は実際には' safeHead'であり、 'safeTail'ではありません – 4castle