実際には、あなたが質問に与えた機能はうまくコンパイルされます。 myzip
のリスト上の任意の作品種類a
とb
という明示的な型シグネチャを持つ
myzip :: [a] -> [b] -> [(a, b)]
myzip (a:b) (z:g)
| b == [] = []
| g == [] = []
| otherwise = (a, z) : myzip b g
:あなたは何を持っていたことは代わりにした場合は、引用されてきたエラーを取得します。しかし、b == []
とg == []
を使用しました。等価演算子は、Eq
タイプのクラスのメンバーであるタイプでのみ、任意のタイプで定義されたではないため、記述したコードは指定したタイプと一致しません。
これはエラーメッセージがかなり簡単に言うものですが、学習していてまだクラスを入力していない場合は、少し不明です。
あなたはa
とb
がEq
型クラスのメンバーである必要があり、その後、あなたが与えたコードが動作することを言ってmyzip
のための型シグネチャを変更する場合:
myzip :: (Eq a, Eq b) => [a] -> [b] -> [(a, b)]
それとも、型シグネチャを残す場合GHCは実際にあなたが==
演算子を使用したという事実からこのタイプを推測しています。コードはそのままの状態でコンパイルされます。
しかし、リストは==
演算子を使用せずに行うことができます空であるかどうかをチェックするので、あなたはそれが本当に任意の種類a
とb
上で動作しないようにmyzip
を書くことができます。一つの方法は、null
関数を使用することである。
myzip :: [a] -> [b] -> [(a, b)]
myzip (a:b) (z:g)
| null b = []
| null g = []
| otherwise = (a, z) : myzip b g
が、はるかに一般的な方法は、単にベースケースがパターン[]
と仮定するする取得主ケースとの照合と、myzip
を定義する複数の方程式を使用することですリストは空ではありません。
myzip :: [a] -> [b] -> [(a, b)]
myzip (a:[]) _ = []
myzip _ (z:[]) = []
myzip (a:b) (z:g) = (a, z) : myzip b g
このスタイルでは、実装にバグがあることが明らかになりました。あなたは最後のa
またはz
を投げ捨てています。リストが完全に空の場合はありません。
あなたの方程式が、その後myzip (a:b) (z:g)
とを言った、それは実際に遅すぎる間違ったことをチェックしていた、空のリストに対してb
とg
をチェックします。 b
が[]
であるかどうかを確認する必要はありません。リストが空であるかどうかを確認する必要があります。しかし、あなたはすでにそれが空ではないと仮定して、それをa:b
に分解しました。その結果、コード(a)は誤った結果を返すことになります。なぜなら、最後のペアの要素を破棄しなければならないし、(b)引数の1つが空のリストであるときにエラーを生成するからです。リスト上の
再帰は通常より次のようになります。これは正しく動作
myzip :: [a] -> [b] -> [(a, b)]
myzip [] _ = []
myzip _ [] = []
myzip (a:b) (z:g) = (a, z) : myzip b g
。
ありがとうございました!私は投稿をして、ファーストフードを食べに出かけ、よく書かれたよく考えられた答えに戻った。インターネットは魔法のようになり、その上の人々は魔法を使う。あなたは魔法です! <3 <3 <3 – MYV