为什么 foldr 可以带三个参数的函数?

srg*_*hma 5 haskell types arguments function fold

我正在查看一些列表操作并遇到了!!

(!!)                    :: [a] -> Int -> a
xs !! n
  | n < 0     = negIndex
  | otherwise = foldr (\x r k -> case k of
                                   0 -> x
                                   _ -> r (k-1)) tooLarge xs n
Run Code Online (Sandbox Code Playgroud)

该函数(\x r k -> ...)具有 type a -> (Int -> a) -> Int -> a,但foldr需要一个只接受两个参数的函数:

foldr            :: (a -> b -> b) -> b -> [a] -> b
foldr k z = go
          where
            go []     = z
            go (y:ys) = y `k` go ys
Run Code Online (Sandbox Code Playgroud)

有人可以向我解释为什么foldr接受一个带有以下类型的 3 个参数的函数a -> (Int -> a) -> Int -> a吗?特别是因为结果应该与第二个参数具有相同的类型?

Zet*_*eta 3

->是右结合的。亦是如此。a -> b -> ca -> (b -> c)因此,你的类型

a -> (Int -> a) ->  Int -> a
Run Code Online (Sandbox Code Playgroud)

是相同的

a -> (Int -> a) -> (Int -> a)
Run Code Online (Sandbox Code Playgroud)

我们可以看到它foldr非常适合 的类型。