2015-12-11 12 views
5

私は**String Newline String**のパターンを関数Splitにマッチさせようとしています。Haskellの連結機能(++)でパターンを一致させることができないのはなぜですか?

split::String -> [String] 
split[] = [] 
split (x++'\n':xs) = [x]++split(xs) 

私はこのエラーを取得しています: Parse error in pattern: x ++ ('\n' : xs)

を、私はここで間違って何をしているのですか?

私は同じ結果を達成するための他の方法がある知っているが、私はこのパターンで何が間違って理解したいと思います。私はHaskell BTWにはかなり新しいです。

+7

コンストラクタでのみパターンマッチングできます。あなたが言うように、 '++'は関数です。 – Bergi

+0

あなたの機能が何をしたいのかを詳しく説明できるなら、非常に役に立ちます。あなたが書いたコードはあまり意味をなさないと思われるので、わかりません。 – dfeuer

+1

大きな質問! 89年に戻って、実際にelem x(_ ++ x:_)= Trueを可能にする言語を構築しました。 elem _ _ = False。私はそれを欠場する。 – pigworker

答えて

11

++は、リストデータ型のコンストラクタではなく、:です。あなたは

:は、リストの先頭に要素を追加し、コンストラクタで
data [a] = [] | a : [a] 

として定義されているリストのデータ型と考えることができます。

(++) :: [a] -> [a] -> [a] 
(++) []  ys = ys 
(++) (x:xs) ys = x : xs ++ ys 

として私たちは、私たちの身近なリストの挙動を模倣する

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

などの当社独自のデータ型のリストを定義することができます。しかし、++は(http://hackage.haskell.org/package/base-4.8.1.0/docs/src/GHC.Base.html#%2B%2Bここではドキュメントで定義された)の関数です。実際には、(Cons val)をパターンとして使用できます。私はあなたにも、あなたがなまけ二つのリストを連結し、1にそれらを結ぶ延期するために使用できるので、

data CList a = Empty | Cons a (CList a) | Concat (CList a) (CList a) 

のように、連結コンストラクタを持つタイプを定義することができます信じています。このようなデータ型では、Concat xs ysの入力に対してパターンマッチングを行うことができますが、2つのリストの境界でのみ動作し、その真ん中では動作しません。

とにかく、私はまだ自分自身をHaskellのためにかなり新しいですが、私はこれがポイントであると思います。

+1

ありがとうございます。私はHaskellの多くの情報源がパターンを構成するものを明確に定義しているわけではないことに少し驚いています。あなたの答えを読んだ後、私は関数のパターンマッチングを探し、[this](https://en.wikibooks.org/wiki/Haskell/Pattern_matching)を見つけました。パターンマッチングはコンストラクタとのみ動作することは明らかです。また、(++)関数を使用して、任意の関数をパターンで使用できないことを実証します。 – farhanhubble

+3

後継の場合、パターンマッチングの正式なセマンティクスは、[Haskell report](https://www.haskell.org/onlinereport/haskell2010/haskellch3.html#x8-580003.17)で定義されています。 – user2407038

+1

@farhanhubble私はあなたが*本当に悪い*ソースに従っているか、それとも正しく読まなかったかを嫌っています。 AFAIK *すべての良い情報源がこれを明確に説明します。 – Bakuriu

5

可能性があります。その後、"a\nb\nc"を照合するとx = "a", xs = "b\nc"またはx = "a\nb", xs = "c"が生成され、どちらを使用するかを決める特別なルールが必要になります。機能に対してマッチングすることは合理的に一般的に実装することも不可能です:あなたはx与えられたf xを見つける必要がある、と考えられるすべてのxを試みるよりも、この他を行うには方法はありません。

+0

ありがとう@Alexey Romanov。私は原因としてあいまいさを考えましたが、他のあいまいさがある場合には、Haskellが示しているようなもっと冗長なエラーメッセージが予想されました。 – farhanhubble

+0

@farhanhubbleロジックは基本的には:これらの問題のため、関数ではコンストラクタでのみ一致することはできません。特定の関数があいまいさを与えるかどうかを調べて確認するのは意味がありません。代わりに、パターンの文法ルールがコンストラクタを必要とするように定義されているため、解析エラーが発生します。しかし、 '++'はコンストラクタではないと言うより良いメッセージがあります。 –

+0

あいまいさは最大の問題でもありません。最大の問題は、おそらく関数のマッチングが停止問題を解決することと等価であり、(等価的に)有限時間に無限領域を列挙する能力が必要であるということです。 –

関連する問題