我刚接触 Haskell 并正在阅读《Haskell基础教程》。
顺便说一下,这个问题是普遍的问题,与这本书无关,我选取此问题只是为了举例说明。
在第10章第10.5节Q5的f部分中:
以下都是非常类似于你已经看到的简单折叠,但每个都至少有一个错误。请修复它们并在 REPL 中进行测试。
f) foldr const 'a' [1..5]
它会出现以下错误:
简单地说,这里不能使用 1 作为 Char。
但我在这一章节中读到,Fold 就像文本重写器,用函数替换 cons(:),用累加器替换空列表。因此结果就是(我缩短了列表):
foldr const 'a' [1..2]
to
(1 `const` (2 `const` 'a'))
它在工作中没有编译器错误。
那么出了什么问题呢? 为什么第一个不起作用,而重写后的代码可以?
但我发现在重写的表单中,const
有两种形式。
Int -> Int -> Int
and
Int -> Char -> Int
可能是由于这个原因,我把const
的类型修复成了这样。
cont :: Int -> Int -> Int
cont = const
现在当我开始使用它时
(1 `cont` (2 `cont` 'a'))
Couldn't match expected type `Int' with actual type `Char'
似乎当我们在使用Haskell的多态函数时,无法将其用于其他形式。也许应该将列表折叠描述为以下内容:折叠就像文本重写器,将cons(:)替换为函数,修复函数类型并将空列表替换为累加器。请分享您对此的看法。是否只有Haskell而其他类型的语言也有相同的行为?或者我完全错了?
map show ['a', 1 :: Int]
相同,即使map f [a, b]
=[f a, f b]
且你可以编写[show 'a', show (1 :: Int)]
。这是因为它们不是相同的f
:show :: Char -> String
和show :: Int -> String
(或者使用TypeApplications
,show @Char
和show @Int
)是不同的函数,同样的道理也适用于const @Int @Char
和const @Int @Int
。 - Jon Purdy