问题
I'm trying to write a function which behave like this:
correctCards :: [Card] -> [Card] -> Int
It takes two lists of type Card and check for how many cards are the same. Here is my code:
correctCards answer guess = foldr step acc guess
where
acc = 0
step acc guess
| elem (head guess) answer = acc + 1
| otherwise = acc
But the types are not match. Can someone tell me where I went wrong? Thanks.
回答1:
Have a look at foldr
's type:
foldr :: (a -> b -> b) -> b -> [a] -> b
Now, that means that the function you supply must be of type a -> b -> b
. Given the following code:
foldr step 0 cards
-- cards :: [Card]
-- 0 :: Integer
-- step :: ???
what should the type of step
be? Given by our arguments, a
should be Card
and b
should be Integer
:
-- concrete type of `foldr` in this case
foldr :: (Card -> Integer -> Integer) -> Integer -> [Card] -> Integer
Therefore, step
should have the type (Card -> Integer -> Integer)
. Compare this to your step function:
step acc guess
| elem (head guess) answer = acc + 1
| otherwise = acc
In this case step
is Integer -> [Card] -> Integer
. And that's not the correct type. Instead, you want
step guess acc
| elem guess answer = acc + 1
| otherwise = acc
Note that step
only takes a single, not a whole list.
来源:https://stackoverflow.com/questions/25722198/how-to-use-foldr-correctly-in-haskell