当我询问 foldl 类型时,我看到的是:

*Main> :t foldl
foldl :: Foldable t => (b -> a -> b) -> b -> t a -> b

在这种情况下,什么是 t a

我想这意味着该函数正在使用 Foldable 参数化的 a 但我什至不确定语法。例如,为什么我不能用 t a 替换 Foldable a

而且,奖金问题,如果我必须自己定义 foldl,我将从基本情况开始
foldl f b [] = []

但是如果基本情况需要一个列表,那么接受 Foldable 就没有多大意义了。我可以用作基本情况的“空可折叠”是什么?

最佳答案

Foldable 是一种叫做“类型类”的东西。说 Foldable t => 声明 t 必须实现 Foldable 的要求。但是, t 仍然是 t ,并且不会像在 Java 中那样折叠为对 Foldable 接口(interface)的引用。这就是为什么你不能只有 Foldable a

一定要查看 https://hackage.haskell.org/package/base-4.10.1.0/docs/Data-Foldable.html 以了解 Foldable 的要求以及哪些方法可以帮助您。

无论如何,如果您想使用 Foldable 的方法之一,那么要么使用已知的 Foldable 类型,如 Set :

import qualified Data.Set as S
import Data.Foldable

sumSet :: (Num n) => S.Set n -> n
sumSet ns = foldl' (\ n acc -> n + acc ) 0 ns --make this pointfree if you want

或者您可以采用类型参数并将其限制为可折叠:
sumFld :: (Num n, Foldable f) => f n -> n --different signature
sumFld ns = foldl' (\ n acc -> n + acc ) 0 ns --same implementation!

以下打印 6,两次:
main :: IO ()
main = print (sumSet $ S.fromList [1, 2, 3]) >> print (sumFld $ S.fromList [1, 2, 3])

关于haskell - 我不确定我是否理解 haskell 中 foldl 函数的类型定义,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49036437/

10-09 15:54