0

リストのリスト内のすべての要素が同じ長さであるかどうかを知るために、haskell で関数を作成しようとしています。(以前の投稿で回答を検索しましたが、どれも機能しません)。

sameLength :: [[t]] -> String
sameLength [] = "Empty list"
sameLength [[items]]
    | and $ map (\x -> length x == (length $ head [[items]])) [[items]] = "Same length"
    | otherwise = "Not the same length"

問題は、それが機能しないことです:

*Main> :l test.hs
[1 of 1] Compiling Main             ( test.hs, interpreted )
Ok, modules loaded: Main.
*Main> sameLength []
"Empty list"
*Main> sameLength [[1,2],[3,4]]
"*** Exception: test.hs:(2,1)-(5,39): Non-exhaustive patterns in function sameLength

*Main> sameLength [[1,2]]
"*** Exception: test.hs:(2,1)-(5,39): Non-exhaustive patterns in function sameLength

どこに問題があるのか​​ よくわかりません。パラメータが空のリストである場合とそうでない場合を扱います。私が間違っている ?私は何か見落としてますか ?

ご協力いただきありがとうございます :)

4

2 に答える 2

4

パターン[x]は、1 つの項目を含むリストに一致しますx。したがって、パターンは[[items]]、1 つの項目を含む 1 つのリストに一致します。必要なのは、2 番目のケースですべての空でないリストに一致することです。しかし、空のリストはすでに照合されているため、削除により、まだ照合されていないものと単純に照合する必要があります。

sameLength :: [[t]] -> String
sameLength [] = "Empty list"
sameLength items = -- Code here
于 2015-03-28T13:06:48.110 に答える
3

ここには多すぎ[..]ます:

sameLength [[items]] 

(シルヴィオがとてもよく説明したように) - 試してみてください

sameLength items 

代わりは。

さらにa == a、頭の長さが頭の長さと同じかどうかを確認する必要はありません`(もちろん)ので、次のようなことをお勧めします。

sameLength :: [[a]] -> Bool
sameLength []     = True
sameLength (h:tl) = all ((length h ==) . length) tl

Bool結果はもっと便利で自然だと思うので

これはどのように作動しますか?

all述語とリストを取り、リストの各要素に対して述語が成り立つかどうかをチェックします -(length h ==) . length = \xs -> length h == length xs述語は、与えられたリストxsがヘッドリストと同じ長さを持っているかどうかをチェックしますh- したがって、上記の注意により、これをチェックするだけで済みますテールリストでtl

述べる

空のリストのすべての要素が同じ長さであるべきかどうかを議論することができますが、答えはイエスであるべきだと思います;)

Prelude> sameLength [[1,2],[3,4]]
True
Prelude> sameLength [[1,2],[3,4,5]]
False
Prelude> sameLength [[1,2]]
True
Prelude> sameLength []
True

パフォーマンスが気になる場合

(またはポイントフリースタイルが気に入らない)

sameLength :: [[a]] -> Bool
sameLength []     = True
sameLength (h:tl) = let l = length h
                    in all (\xs -> length xs == l) tl
于 2015-03-28T13:11:25.827 に答える