4

takeIfHaskell を勉強して、条件を指定すると、リストが条件を満たすすべてのリストの要素を返す関数をコーディングしようとしています。

望ましい出力の例:

takeIf (>0) [] --> []
takeIf (>0) [-1, 0, 1, 2] --> [1,2]

私はこの定義を試しました:

takeIf cond [] = []
takeIf cond (x:xs) = if (cond x) 
                    then x:(takeIf cond xs)
                    else []:(takeIf cond xs)

しかし、うまくいきません。

私の最初の質問は次のとおりです。

:t takeIf --> ([a] -> Bool) -> [[a]] -> [[a]]

なぜ?なぜだめですか:

:t takeIf --> (a -> Bool) -> [a] -> [a]

このコードを機能させるにはどうすればよいですか?

これは私が得るエラーです:

ここに画像の説明を入力

役立つ場合は、私が使用していますghci

4

3 に答える 3

10
[]:(takeIf cond xs)

ここでは、 [] を新しい最初の要素として の結果に追加しようとしていますtakeIf cond xs。はリストなので[]、GHC はそれから の結果はtakeIf cond xsリストのリストでなければならないと推測します。takeIf の結果はその引数と同じ型を持つため、これはxsリストのリストでなければならないことを意味します。そして、xは の要素であるため、結果的にリストxsでなければなりません。x

[]:「リストに何も追加しない」という意味のようですが[]、何もありません。空のリストです。[] : []、あなたに与えません[]、それはあなたに与えます[[]]。同様に、それは適切に型付けされていないことを除いて、[] : [1,2,3]あなたに与えるでしょう。そのため、実際にあなたに与えるのは型エラーです。[[], 1, 2, 3]

リストの先頭に何も追加したくない場合は、リストの先頭に何も追加しないでください。つまり、someList代わりに[] : someList.

于 2012-06-02T17:06:56.207 に答える
3

sepp2kは私よりも速かったので、あなたが見てみたいと思うかもしれないことを付け加えたいと思いますfilter。それはまさにあなたが再実装しようとしている関数であるソースです。
これが実際のソースです

filter :: (a -> Bool) -> [a] -> [a]
filter _pred []    = []
filter pred (x:xs)
  | pred x         = x : filter pred xs
  | otherwise      = filter pred xs
于 2012-06-02T17:14:51.197 に答える
0

代替手段は折り目です、例えば

filter' f = foldr go [] where 
   go x xs = if f x then x:xs else xs
于 2012-06-03T10:24:15.090 に答える