How to use foldr correctly in Haskell?

六眼飞鱼酱① 提交于 2020-01-04 23:05:30

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!