为什么foldr const 0“ tacos”无法在Haskell中编译?

问题描述 投票:0回答:3

所以foldr const 0 "tacos"应该解散成类似

0 const ('t' const ('a' const ('c' const ('o' const 's')))). 

我认为它只会在0 const ('t'处停止,因为Haskell是惰性计算的,而const只接受第一个参数。因此,从理论上讲,该函数是否不适用于1?

虽然这不起作用。用0替换""也不起作用。有人知道为什么吗?

谢谢!

haskell fold
3个回答
2
投票

为什么文件夹const 0“ tacos”在Haskell中不能编译?

因为:

> foldr const 0 "tacos"

<interactive>:1:13: error:
    • No instance for (Num Char) arising from the literal ‘0’
    • In the second argument of ‘foldr’, namely ‘0’
      In the expression: foldr const 0 "tacos"
      In an equation for ‘it’: it = foldr const 0 "tacos"

因此,如果我们进行调查,我们会看到(请忽略@[],它是一种类型应用程序,可以使我们的对话更加简单)

> :t foldr @[] const 0
foldr @[] const 0 :: Num b => [b] -> b

因此您需要提供Num实例的项目列表。但您提供了:

> :t "tacos"
"tacos" :: [Char]

玉米饼有时是包裹肉和米饭的玉米饼。但是有时,例如现在,它们是字符列表。字符不是Num的实例。这就是错误要告诉您的内容。


0
投票

查看文件夹的类型(让我们专门研究列表):

foldr :: (a -> b -> b) -> b -> [a] -> b

您已经提供了参数(并且我们将Int专门指定为0)

const :: a -> b -> b  -- this looks off...
0 :: b                -- this means b = Int
"tacos" :: [a]        -- this means a = Char

稍等。检查const的实际类型:

const :: a -> b -> a

看到问题了吗?您以错误的顺序获得了const的参数。尝试使用(flip const)而不是const获得所需的答案,尽管它没有所需的性能特征。

您可能还想尝试foldl',它从左到右累积结果。


以您最初编写它的方式,类型系统必须将const的类型签名a -> b -> a与文件夹的参数类型a -> b -> b统一,这只能通过统一a = b来完成。但是,由于a = Charb = Int,无法执行此统一。

[表达式的正确“解散”(foldr的工作方式是将:替换为const,将[]替换为0

't' : 'a' : 'c' : 'o' : 's' : []
==> let's write it with (:) as a prefix funtion
(:) 't' ((:) 'a' ((:) 'c' ((:) 'o' ((:) 's' [])))) 
==>
const 't' (const 'a' (const 'c' (const 'o' (const 's' 0))))

但由于上述所有const都必须具有相同的类型的限制,因此不能。

注意0如何显示在innermost常量而不是最外部。


0
投票

我猜你犯了两个错误:一个很小,另一个稍微小一些。

  1. 要将带字母的变量(例如const)用作运算符,必​​须将其括在反引号中:

    "hello" `const` 1 = "hello"
    "hello" const 1 -- nonsense
    
  2. 您将foldrfoldl部分混在一起:

    foldr (#) n [1..3] = 1 # (2 # (3 # n))
    foldl (#) b [1..3] = ((b # 1) # 2) # 3
    

确实,foldlconst正常工作:

foldl const 0 "tacos"
  = ((((0 `const` t) `const` a) `const` c) `const` o) `const` s
  = 0

这种愚蠢的计算效率很低,即使结果始终相同,也需要遍历整个列表才能将const 0应用于每个元素!

© www.soinside.com 2019 - 2024. All rights reserved.