0

適用されたフィルター関数の結果が空のリストであるかどうかを確認する関数を作成するよう求められました。次のアプローチを試しましたが、言及されたエラーが発生します。

isListEmpty ::((a -> Bool) -> [a] -> [a]) -> Bool
isListEmpty f       | length f == 0 = True
                    | otherwise = False

エラー:

...- Type error in application
*** Expression     : length f
*** Term           : f
*** Type           : (b -> Bool) -> [b] -> [b]
*** Does not match : [a]

アイデアは、高次関数を実践することです。どうすればこれを解決できますか?

4

4 に答える 4

3

型の注釈が間違っているようです。次の解決策を検討してください。

isListEmpty :: (a -> Bool)        -- filtering function
            -> [a]                -- given list
            -> Bool               -- the result
isListEmpty f = null . filter f

いくつかの例:

> isListEmpty odd [2, 4]
True
> isListEmpty odd [1, 2, 4]
False
> 

lengthチェックを行うためにリスト全体をループする必要があり、リストが無限になる可能性があるため、を使用することは最善のアイデアではありません。nullこの状況を処理できます:

> isListEmpty even [1..]
False
> 

編集1

私たちの質問では、組み込みのフィルター関数を引数として使用するよう求められました

それが何を意味するのかよくわかりませんが、これをしたいかもしれません:

isListEmpty :: ([a] -> [a]) -> [a] -> Bool
isListEmpty = (null .)

使用例:

> isListEmpty (filter even) [1..]
False

私が間違っている場合は、意図した関数呼び出しの例を教えてください。

于 2013-01-27T01:55:45.703 に答える
3
isListEmpty ::((a -> Bool) -> [a] -> [a]) -> Bool
isListEmpty f       | length f == 0 = True
                    | otherwise = False

関数の最初のパラメーターはisListEmpty、名前を付けた関数でありf、その型は関数であり、関数は署名付きの型を取り、 type を生成するため、これ(a -> Bool) -> [a] -> [a].にフィードfすると機能しません。lengthlength[a]Int

:t lengthこれは、ghci に移動して次のように入力することで確認できます[a] -> Int

最初に型を持つリストに f を適用すると、 andを使用して、それが空かどうかを確認[a]できます。ただし、関数はリストが空かどうかをテストするための慣用的な方法であるため、代わりに使用することをお勧めします。length==0null

同様の関数を作成する方法の例を編集して追加します。

drop や init などの別の関数を実行した後、リストの長さを知りたいとしましょう。最初に、すべての引数を使用して完全に関数を記述します。

manipulateList :: ([a] -> [a]) -> [a] -> Int
manipulateList fn lst = length (fn lst)

length (fn lst)関数合成でこれを書き直す代わりに(length.fn) lst

manipulateList :: ([a] -> [a]) -> [a] -> Int
manipulateList fn lst = (length.fn) lst

lstこれで、代数方程式の場合と同じように、両側の をキャンセルできます。

manipulateList :: ([a] -> [a]) -> Int
manipulateList fn = (length.fn)

これで、関数を取り、それに適用されたfn後のリストの長さを見つける高階関数ができました。fn

于 2013-01-27T01:44:05.743 に答える
1

最初: この関数を入力が 1 つしかないかのように扱うため、エラーが発生します。リストです。一方、型シグネチャはatoBoolと twoから関数を要求しますlists of type a.

2番目:あなたは、フィルター関数が適用されたリストが空であるかどうかをテストする関数を作成する必要があると言いました。ただし、リストが空の場合はテストするだけで、フィルター関数は適用されません ((上記のように) 関数で何かを行うことさえしませんでした)。

3 番目: ちょっとしたヒント: から始める

isListEmpty f xs | length xs == 0 = True
                 | otherwise      = ...  ||  isListEmpty f ...

に何かを記入する必要があります...||わからない場合は、ブール値の「OR」を表します。

于 2013-01-27T01:51:57.967 に答える
1

あなたはただ行うことができます:

null $ (filter (>2) [2,1,0]) ==> True
null $ (filter (>2) [2,1,9]) ==> False

と :

null :: [a] -> Bool
null [] = True
null _  = False

またはHOFを使用する(前述のように、このソリューションは間違っています。HOFは使用しません)

hof_null filter 
    | (null $ filter) = True
    | otherwise       = False


not_null (filter (>2) [1,1,3]) ==> False
not_null (filter (>2) [1,1,1]) ==> True

....

最後の試み (Davorak に感謝)

hof_null fn = null.fn
于 2013-01-27T01:53:15.837 に答える