2016-09-13 9 views
1

奇数関数を使用してフィルタに非常によく似た関数を書いて、奇数を任意の奇数の2乗で返す関数を作成したいとします。Intsのリストを取得し、任意の奇数の二乗でリストを返す関数を作成する

gchi> sqrodd [1,2,3,4,5] 
[1,2,9,4,25] 

私が持っていると近くにあると考えていることは

sqrodd :: (a->Bool) -> [a] -> [a] 
sqrodd odd []  = [] 
sqrodd odd (x:xs) = if odd x 
        then (x*x) :sqrodd odd xs 
        else x : sqrodd odd xs 

ですが、私は関数定義でエラーが

「実際のタイプ [a]と期待されるタイプ a -> Boolと一致しませんでした」と言ってます

答えて

5

あなた自身を書いたように、あなたが引数としてリストを取り、別のリストを返す関数をしたいので、代わりに型シグネチャ

sqrodd :: (a->Bool) -> [a] -> [a] 

を有しているとあなたはこのようになります型シグネチャを持つ関数を作る必要があります

sqrodd :: [a] -> [a] 

これはあなたが最初に書いたものです。 このコンパイラは、この関数の最初の引数は(a - > bool)の関数であると予想しているためです。 上記のように、引数リストからoddを削除し、型シグネチャを変更する必要があります。これは、引数としてフィルタ関数を期待するのではなく、関数が関数preledeから奇数を使用するようにします。

それを行うための別の方法は、例えばsqrfiltered、とあなたが機能し、部分的に適用されるが

sqrodd = sqrfiltered odd 

テストし、それは右でなければならないsqrfilteredとして、あなたはsqroddを定義することができます名前変更されます。

6

sqroddの機能には、の2つのパラメータがあります。最初は奇妙ですness-predicate a -> Bool、第2の要素は[a]のリストです。あなたの使用例では、a -> Bool述語の代わりに、の最初の引数として[1..5]を渡します。

しかし、あなたが本当にしたいことはにありません単一パラメータ機能sqrodd :: [a] -> [a]には2つのパラメータ、すなわち変更sqroddを持っているだけでthe function odd from the Preludeを使用しています。あなたがどんなタイプaの要素にodd(*)を適用できるというのは本当ではありませんので、あなたがまだあなたのsqrodd型ではもう少し制限する必要があります

注意。あなたはその次のハードルを乗り越えるためにそこに着くと、型板を読みたいかもしれません。

0

フィルタ関数は、リスト内の各要素を調べ、その条件を満たす要素のみを含む新しいリストを返します。

しかし、達成したいのは、リストを新しいリストに変換することです。新しいリストには古いものと同じ数の要素があります。あなたは何も除外していません。いくつかのルールに従って要素をあるリストから別のリストにマッピングしています。

次の2つの方法で関数を記述できます。

oddSquared, oddSquared' :: [Int] -> [Int] 

oddSquared l = [ if (x `mod` 2 /= 0) then x^2 else x | x <- l ] 

oddSquared' = map (\x -> if odd x then x^2 else x) 
関連する問題