2

私は現在、haskell のボード評価に取り組んでいます。複数のパラメーターを持つ関数で map を使用しようとしています。これに関する他のSOの質問を読みましたが、型エラーが発生し続けるため、おそらくHaskell型を誤解しているだけです(私はPythonプログラマーです)。いずれにせよ、コードは次のとおりです。

scorePiecesRow [] _ = 0
scorePiecesRow (x:xs) y
    | x == y            = 1 + (scorePiecesRow xs y)
    | x == '-'          = 0 + (scorePiecesRow xs y)
    | otherwise         = -1 + (scorePiecesRow xs y)

scorePieces [] _ = 0
scorePieces board y =  foldr (+) 0 (map (scorePiecesRow y) board)

scorePiecesRow"wwwb--" 'w'(これは を返します) のようなものを渡すと問題なく動作しますが、 (たとえば、 を返す必要がある)3を呼び出すとすぐに、一連の型エラーが発生します。scorePiecesscorePieces ["www", "bb-"] 'w'1

<interactive>:37:14:
    Couldn't match expected type `Char' with actual type `[Char]'
    In the expression: "www"
    In the first argument of `scorePieces', namely `["www", "bb-"]'
    In the expression: scorePieces ["www", "bb-"] 'w'

<interactive>:37:21:
    Couldn't match expected type `Char' with actual type `[Char]'
    In the expression: "bb-"
    In the first argument of `scorePieces', namely `["www", "bb-"]'
    In the expression: scorePieces ["www", "bb-"] 'w'

<interactive>:37:28:
    Couldn't match expected type `[Char]' with actual type `Char'
    In the second argument of `scorePieces', namely 'w'
    In the expression: scorePieces ["www", "bb-"] 'w'
    In an equation for `it': it = scorePieces ["www", "bb-"] 'w'

エラーメッセージに少し混乱しています。たとえば、最初のものは、それが expected であることを示していCharますが、の最初の引数はscorePiecesRowtake[Char]です。誰かがこれに光を当てることができれば、それは大歓迎です!

4

2 に答える 2

4

Haskell は型を推測しますが、コードを文書化し (機械でチェックされた方法で!)、仮定を確認するためにも、それらを書き出すことは通常非常に価値があります。ここで、Haskell の型推論エンジンの作業を実行して、これらの関数についてわかっていることを把握できます。

scorePiecesRowは数値に追加されるため、結果は型クラス(が定義され1 + (scorePiecesRow xs y)ている場所) にある必要があることがわかっています。Num(+)

scorePiecesRow :: Num a => ... -> a

さらに、引数のパターン マッチングを見ると、最初の引数がリストでなければならないことが簡単にわかります。

scorePiecesRow :: Num a => [b] -> ... -> a

を使用して最初の引数の要素を 2 番目の引数と比較するため、(==)それらは同じ型であり、型クラス内にある必要があることがわかりますEq(ここで(==)が定義されています!)。

scorePiecesRow :: (Num a, Eq b) => [b] -> b -> a

最後に、最初の引数の要素が と等値で比較される'-'ので、実際には でなければならないことがわかりますCharStringは同義語であるため、それ[Char]を帰することができます。

scorePiecesRow :: (Num a) => String -> Char -> a

scorePieces私たちはそれを学ぶために同じことをすることができます

scorePieces :: Num a => String -> String -> a

ここに問題があります。scorePieces ["www", "bb-"] 'w'つまり、 with a [String]and a Charwhileは a and anotherをscorePieces期待しています。StringString

Stringエラーはこれを正確に伝えていますが、と[Char]は同じであり、GHC はエラーを報告するときに型を単純な形式に減らす傾向があるため、少し混乱します。

于 2013-11-08T02:01:32.803 に答える