2017-01-16 6 views
2

私はハスケルで文字列タプルを失っています。 タプル文字列のパターンマッチングリスト

type Book = [(String, String)] 

は、その後、私は空のブックを宣言:

emptyBook :: Book 
emptyBook = [] 

そして今、私は本に要素を挿入する機能を作成したい 私はそのためのタイプを宣言しました。私の解決策:

insert :: String -> String -> Book -> Book 
insert a b emptyBook = (a,b) : [] 
insert a b (x : xs)= (a, b) : (x:xs) 

しかし、機能の挿入が機能していません。コンパイラはモジュールをロードしますが、「パターン一致は冗長です」という警告を出します。挿入"a" "1" [("b","2")]を実行

は間違ってここに行くいただきました!あなたは知っています代わりに[("a","1"),("b","2")]

[("a","1")] を与えますか?

+0

イッツ・タプル(S)*と同じではなく、*タプル(S)* 。 –

答えて

4

insert a b emptyBook = (a,b) : [] 

は、3つの一般的な引数abemptyBookの関数としてinsert定義します。さて、最後には実際に使用されていないが、それは違いはありません - その句は関係なく、あなたが渡すものを引数、成功しないだろう

も第三引数トップレベルの定義emptyBookは - 。基本的にはこれが作ります関数の範囲内で、emptyBookは、それが空であるかどうかに関係なく、あなたが渡したすべての本になります。 、あなたはemptyBookが上一致しなければならない定数になりたい場合は

[email protected]:~$ runhaskell -Wall /tmp/wtmpf-file2776.hs 

/tmp/wtmpf-file2776.hs:7:12: Warning: 
    This binding for ‘emptyBook’ shadows the existing binding 
     defined at /tmp/wtmpf-file2776.hs:4:1 

/tmp/wtmpf-file2776.hs:7:12: Warning: 
    Defined but not used: ‘emptyBook’ 

GHCが実際にあなたのコードでこの実際の問題を強調し、警告を与えることができ、あなたがそれを言うならば寛大な警告を与えるためにこれが新しくバインドされた引数変数ではないことを明示的にしなければなりません。オプションのカップル: - それはあまり効率的で、より多くの、より少ない一般的だ

  • (は推奨しない)は

    insert a b book 
        | book==emptyBook = (a,b) : [] 
    insert a b (x : xs) = (a, b) : (x:xs) 
    

    我々は、一般的にはHaskellでの等価比較を避けるパターンマッチングするのではなく、等価比較を使用しますパターンマッチングよりエラーが発生しやすい

  • は(非常ない推奨)実際には、パターンマッチングに文字通り[]を挿入する(テンプレートHaskellはまた機能するであろう)、Cプリプロセッサマクロを使用します。あなた[]という名前の変数を持つことができないので、これは正しいことを行います。このようなマクロ定義は、Haskellので非常にうまく機能しません

    {-# LANGUAGE CPP #-} #define emptyBook [] insert :: String -> String -> Book -> Book insert a b emptyBook = (a,b) : [] insert a b (x : xs) = (a, b) : (x:xs) 

    - 、彼らは言語のスコープの完全に忘れていることはできませんエクスポートすることなど。

  • (非常には推奨しない)はパターン同義語を使用しています。これらは、基本的に私はCPPマクロで上記のやった行動を達成するための近代的な、Haskellのネイティブな方法です:

    {-# LANGUAGE PatternSynonyms #-} 
    
    pattern EmptyBook :: Book 
    pattern EmptyBook = [] 
    
    insert :: String -> String -> Book -> Book 
    insert a b emptyBook = (a,b) : [] 
    insert a b (x : xs) = (a, b) : (x:xs) 
    

だから、何推奨される解決策でしょうか?ウィレム・ヴァン・オンセム(Willem Van Onsem)は次のように言います。あなたはその句をまったく必要としません。それはすでに第二節の特別なケースです!

insert :: String -> String -> Book -> Book 
insert a b (x : xs) = (a, b) : (x:xs) 

...

insert a b (x : xs) = (a, b) : x : xs 

又は

insert a b xxs = (a, b) : xxs 

又は

insert a b = ((a, b) :) 

又は

import Data.Function.Pointless 

insert=(:).:(,) 
6

私はなぜあなたを得ることはありません:

  1. 使用emptybookをあなたのパターンマッチングの部分には、代わりに[]の。
  2. (x:xs)を式の左と右の部分の両方に繰り返すのはなぜですか。
  3. 空の本と空でない本を区別します。 Haskellは、他の多くの言語と同様に変数のスコープを使用し、Haskellは、変数としてあなたの関数emptybookを見ているので、それは

    動作しないのはなぜ

emptybookはどこかで定義された関数であるとは見られません(少なくともそこにはありません)。したがって、以下のように書くことができます:

insert a b c = (a,b) : [] 

(関数定義の2行目)今度は変数cを定義し、制約(ガード、パターン、...)を入れなかったので、はすべてと一致します。空でないブックも同様です。したがって、ハスケルは常に最初の行を取るでしょう。実際、コンパイラはこれを警告します。それは言う:

haskell.hs:9:1: Warning: 
    Pattern match(es) are overlapped 
    In an equation for ‘insert’: insert a b (x : xs) = ... 

これは、関数定義の最後の行が前の行と重なっていることを意味します。その場合はおそらく何か間違ったことをしているでしょう。

代替

あなたは、単に使用することができます。

insert :: String -> String -> book -> book 
insert a b xs = (a,b) : xs 

かさえ短い:

方が良い代わりにBookを使用するので、さらに、タイプは通常、大文字で示され
insert :: String -> String -> book -> book 
insert a b = (:) (a,b) 

bookです。

+0

これは現在のコードの改良点の一覧ですが、実際にはその質問には答えません。 – lisyarus

+0

@lisyarus:良い点!私はそれを書き換えます。 –

+0

@lisyarus:私は自分の答えを更新しました。より良い? –

関連する問題