Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell foldr导致类型错误,而foldl没有';T_Haskell_Lazy Evaluation_Fold - Fatal编程技术网

Haskell foldr导致类型错误,而foldl没有';T

Haskell foldr导致类型错误,而foldl没有';T,haskell,lazy-evaluation,fold,Haskell,Lazy Evaluation,Fold,我正在学习“Haskell从第一原则开始编程”。在关于折叠列表的章节中,练习5f 当我评估 foldr const 'a' [1..5] 我明白了 没有由文字“1”产生的(Num Char)实例 但是, foldl const 'a' [1..5] 我得到了'a' 我发现褶皱很懒,foldr不会穿过脊椎,foldl会穿过脊椎。但即使看看foldr和foldl的定义 foldr f z [] = z foldr f z (x:xs) = f x (foldr f z xs) fo

我正在学习“Haskell从第一原则开始编程”。在关于折叠列表的章节中,练习5f

当我评估

foldr const 'a' [1..5]
我明白了

没有由文字“1”产生的(Num Char)实例

但是,

foldl const 'a' [1..5]
我得到了
'a'

我发现褶皱很懒,
foldr
不会穿过脊椎,
foldl
会穿过脊椎。但即使看看foldr和foldl的定义

foldr f z []     = z 
foldr f z (x:xs) = f x (foldr f z xs) 

foldl f z []     = z                  
foldl f z (x:xs) = foldl f (f z x) xs
我不明白为什么会有这种类型的错误。我猜想编译器正在根据
z
Char
)的类型推断
x
Num
)的类型,但我看不出它在哪里绘制连接,因为
const
f
不要求它的两个参数是同一类型


有什么想法吗?

好的,看看
foldr::(a->b->b)->b->[a]->b的类型

从右边开始,显然必须有
a
作为
Num
Enum
的实例(因为您使用
[1..5]

接下来,您传入
'a'
,这样您就有了
b~Char

最后,您有函数的
const
——const是
const::a->b->a
——请注意,您现在必须有
a~b
,因为您统一了

a -> b -> b
a -> b -> a
        ^^^^^
但这当然意味着
'a'
必须是
Num
实例的值,而
Char
不是。。。这是您的错误(它抱怨1,因为从左开始,问题变得明显)


另一边的
foldl
foldl::(b->a->b)->b->[a]->b


所以现在你又有了
a
一些
Num
的实例,
b
必须再次是
Char
,但是现在
const
正好合适(只需在const类型中切换
b
a

好,看看
foldr:(a->b->b->b->a]>b

从右边开始,显然必须有
a
作为
Num
Enum
的实例(因为您使用
[1..5]

接下来,您传入
'a'
,这样您就有了
b~Char

最后,您有函数的
const
——const是
const::a->b->a
——请注意,您现在必须有
a~b
,因为您统一了

a -> b -> b
a -> b -> a
        ^^^^^
但这当然意味着
'a'
必须是
Num
实例的值,而
Char
不是。。。这是您的错误(它抱怨1,因为从左开始,问题变得明显)


另一边的
foldl
foldl::(b->a->b)->b->[a]->b


因此,现在您又有了
a
一些
Num
的实例,
b
必须再次是
Char
,但现在
const
正好适合(只需在const类型中切换
b
a

foldl
foldr
调用
f
。这就是
foldr
调用
const x'a'
,但是
foldl
调用
const'a'x
。后者的结果是“a”,这很好,但后者的结果是
x
,这是错误的,因为
x
是一个
Int
,并且结果应该与累加器具有相同的类型(
Char
).

foldl
foldr
使用不同的参数顺序调用
f
。这就是
foldr
调用
const x'a'
,但是
foldl
调用
const'a'x
。后者的结果是“a”,这很好,但后者的结果是
x
,这是错误的,因为
x
是一个
Int
,并且结果应该与累加器的类型相同(
Char
)。

这是一个键入问题。
foldl
的类型为

foldl :: Foldable t => (b -> a -> b) -> b -> t a -> b    
foldr
类型为:

foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b
当您将
foldr
应用于
const
时,您会得到:

foldr const :: Foldable t => b -> t b -> b
接下来,提供
'a'
参数,得到

(foldr const 'a') :: Foldable t => t Char -> Char

因此,当您将
[1..5]
作为参数传递时,它将尝试将
t Char
(Enum a,Num a)=>[a]
统一起来。Type
Char
Enum
类的一个实例,但不是
Num
,这就是您收到此错误消息的原因。

这是一个键入问题。
foldl
的类型为

foldl :: Foldable t => (b -> a -> b) -> b -> t a -> b    
foldr
类型为:

foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b
当您将
foldr
应用于
const
时,您会得到:

foldr const :: Foldable t => b -> t b -> b
接下来,提供
'a'
参数,得到

(foldr const 'a') :: Foldable t => t Char -> Char

因此,当您将
[1..5]
作为参数传递时,它将尝试将
t Char
(Enum a,Num a)=>[a]
统一起来。Type
Char
Enum
类的一个实例,但不是
Num
,这就是您收到此错误消息的原因。

正如其他人所说,
foldl
foldr
中的参数顺序不同。改用
翻转常数

> foldr (flip const) 'a' [1..5]
'a'

正如其他人所说,a
foldl
foldr
中的参数顺序是不同的。改用
翻转常数

> foldr (flip const) 'a' [1..5]
'a'

啊,没错。当出现类型错误时,我必须养成先检查类型定义的习惯。谢谢是的-这就是你需要知道的99%的关于Haskell保暖的知识:检查类型;)啊,没错。当出现类型错误时,我必须养成先检查类型定义的习惯。谢谢是的-这就是你需要知道的99%的关于Haskell保暖的知识:检查类型;)“查看定义[…]我不明白为什么会出现这种类型错误”-诊断类型错误时不要查看定义,请查看类型!“看看这些定义[…]我搞不懂