終了させる
問題はこの場合
getIndex (x:xs) y
| length x <= y = 1 + getIndex xs y
| otherwise = 0
where (x:xs) = sortList (x:xs)
どれがどれだか混乱して(x:xs)
います。代わりに行う必要があります
getIndex zs y
| length x <= y = 1 + getIndex xs y
| otherwise = 0
where (x:xs) = sortList zs
与える
Main> main
[[],[4],[4,3],[3,5,3],[3,5,5,6,1]]
3
*Main> getIndex [[],[2],[4,5]] 1
2
*Main> getIndex [[],[2],[4,5]] 5
3
これにより、少なくともソートされたリスト内の最初の長さのリストの数が得られます。これは、 「元のリストの長さは最大でいくつですか?」y
という質問に実際に答えます。y
どうすれば他の事実を知ることができますか?
元のリストからの位置が必要な場合は、次を使用してエントリに位置をタグ付けできますzip
。
*Main> zip [1..] [[4],[3,5,3],[4,3],[3,5,5,6,1],[]]
[(1,[4]),(2,[3,5,3]),(3,[4,3]),(4,[3,5,5,6,1]),(5,[])]
それらを操作するためのユーティリティ関数を作成しましょう。
hasLength likeThis (_,xs) = likeThis (length xs)
次のように使用できます。
*Main> hasLength (==4) (1,[1,2,3,4])
True
*Main> filter (hasLength (>=2)) (zip [1..] ["","yo","hi there","?"])
[(2,"yo"),(3,"hi there")]
つまり、 より長い長さの最初のリストのインデックスを与える関数を書くのが簡単になりましたy
:
whichIsLongerThan xss y =
case filter (hasLength (>y)) (zip [1..] xss) of
[] -> error "nothing long enough" -- change this to 0 or (length xss + 1) if you prefer
(x:xs) -> fst x
これにより、
*Main> whichIsLongerThan [[4],[3,5,3],[4,3],[3,5,5,6,1],[]] 2
2
*Main> whichIsLongerThan [[4],[3,5,3],[4,3],[3,5,5,6,1],[]] 3
4
*Main> whichIsLongerThan [[4],[3,5,3],[4,3],[3,5,5,6,1],[]] 0
1
短い?
しかし、同様のトリックを行うことができます:
whichIsShorterThan xss y =
case filter (hasLength (<y)) (zip [1..] xss) of
[] -> error "nothing short enough" -- change this to 0 or (length xss + 1) if you prefer
(x:xs) -> fst x
だからあなたは得る
*Main> whichIsShorterThan [[4],[3,5,3],[4,3],[3,5,5,6,1],[]] 2
1
*Main> whichIsShorterThan [[4],[3,5,3],[4,3],[3,5,5,6,1],[]] 1
5
*Main> whichIsShorterThan [[4],[3,5,3],[4,3],[3,5,5,6,1],[]] 0
*** Exception: nothing short enough
一般化された
そこで共通のテーマを引き出してみましょう。
whichLength :: (Int -> Bool) -> [[a]] -> Int
whichLength likeThis xss =
case filter (hasLength likeThis) (zip [1..] xss) of
[] -> error "nothing found" -- change this to 0 or (length xss + 1) if you prefer
(x:xs) -> fst x
私たちができるように
*Main> whichLength (==5) [[4],[3,5,3],[4,3],[3,5,5,6,1],[]]
4
*Main> whichLength (>2) [[4],[3,5,3],[4,3],[3,5,5,6,1],[]]
2