简体   繁体   English

无法匹配预期类型`[([Char],a0)]'与实际类型`([Char],t0)'Haskell

[英]Couldn't match expected type `[([Char], a0)]' with actual type `([Char], t0)' Haskell

I am starting to program with haskell. 我开始用haskell编程。 The program I am developing just sums the total of a list with two elementes, for example: 我正在开发的程序只是将一个列表的总和与两个元素相加,例如:

[("book",10),("cookies",2),("icecream",5)]

This should return "17". 这应该返回“17”。 Here i my code: 这是我的代码:

total [] = []
total ([("c",e)]:y) = total y ++ [e]

But while running in GHCi it gives me this error: 但是在GHCi中运行它会给我这个错误:

<interactive>:80:8:
    Couldn't match expected type `[([Char], a0)]'
                with actual type `([Char], t0)'
    In the expression: ("livro", 10)
    In the first argument of `total', namely
      `[("livro", 10), ("bolachas", 2), ("gelado", 5)]'
    In the expression:
      total [("livro", 10), ("bolachas", 2), ("gelado", 5)]

<interactive>:80:21:
    Couldn't match expected type `[([Char], a0)]'
                with actual type `([Char], t1)'
    In the expression: ("bolachas", 2)
    In the first argument of `total', namely
      `[("livro", 10), ("bolachas", 2), ("gelado", 5)]'
    In the expression:
      total [("livro", 10), ("bolachas", 2), ("gelado", 5)]

<interactive>:80:36:
    Couldn't match expected type `[([Char], a0)]'
                with actual type `([Char], t2)'
    In the expression: ("gelado", 5)
    In the first argument of `total', namely
      `[("livro", 10), ("bolachas", 2), ("gelado", 5)]'
    In the expression:
      total [("livro", 10), ("bolachas", 2), ("gelado", 5)]

This is probably very simple but as a beginner I was not able to solve this. 这可能很简单,但作为初学者,我无法解决这个问题。

In the line: 在线:

total ([("c",e)]:y) = total y ++ [e]

the ([("c",e)]:y) does not do what you want. ([("c",e)]:y)不能做你想做的事。 It matches a nonempty list in which the first element is also a list (because of the [...] ) and in which that sublist has exactly one element, which is a pair whose first element equals "c" . 它匹配一个非空列表,其中第一个元素也是一个列表(因为[...] ),并且该子列表中只有一个元素,即第一个元素等于"c" In order to match what you want, you need to write: 为了匹配你想要的东西,你需要写:

total ((c,e):y) = total y ++ [e]

However, this still won't do what you want, as it constructs a list of all of the e values in the input list. 但是,这仍然无法执行您想要的操作,因为它构造了输入列表中所有e值的列表。 To sum them together, you need to do: 要将它们相加,您需要:

total [] = 0
total ((c,e):y) = total y + e

In addition to what @jwodder said, note that there's also another way to approach the problem. 除了@jwodder所说的,还要注意还有另一种解决问题的方法。 Instead of thinking /how/ you would compute the desired value, think about /what/ you do: you take the second element of every list item and then sum those elements up. 不考虑/如何/你将计算所需的值,考虑/你做什么:你采取每个列表项的第二个元素,然后将这些元素加起来。

So you could start by writing two functions, one which takes a list of tuples yielding a list of all the second elements, and another computing the sum of a given list of numbers. 因此,您可以从编写两个函数开始,一个函数采用元组列表,生成所有第二个元素的列表,另一个函数计算给定数字列表的总和。 A good start is to come up with the type signatures but defining the functions to evaluate to undefined : 一个好的开始是提出类型签名,但定义要评估为undefined的函数:

-- Takes a list of tuples and returns all the second elements
getSecondElements :: [(String, Int)] -> [Int]
getSecondElements someList = undefined

-- Computes the sum of a given list of integers
sumOfIntList :: [Int] -> Int
sumOfIntList someInts = undefined

Using these, defining you function is straightforward: 使用这些,定义您的功能很简单:

total myList = sumOfIntList (getSecondElements myList)

You can run this through ghci and it'll type-check, which is a good sign. 你可以通过ghci运行它,它会进行类型检查,这是一个好兆头。 When you try to actually use total , you get an error though because the other two functions are just undefined . 当你尝试实际使用total ,你会收到一个错误,因为其他两个函数都是undefined

Before you go and think about how to implement them, it's a good idea to see whether they exist already. 在你开始思考如何实现它们之前,最好先看看它们是否已经存在。 You can search Hoogle for type signatures and it'll dig up functions matching that signature. 您可以在Hoogle中搜索类型签名,它会挖掘与该签名匹配的功能。 The signature of getSecondElements doesn't yield any hits but the signature for the second yields a lot of hits, and most of those hits don't even talk about Int at all: Hoogle is smart enough to understand that functions which deal on arbitrary types of lists (say: length or head ) may also be applicable. getSecondElements的签名不会产生任何命中,但第二个签名会产生很多命中,而且大多数命中甚至都没有谈论Int :Hoogle足够聪明,可以理解处理任意类型的函数列表(例如: lengthhead )也可能适用。 If you scroll down the page you'll see that there's an existing sum function already! 如果向下滚动页面,您将看到已经有一个现有的sum函数!

For the first function, you can repeat the process (recursively, if you like): in order to get all second-tuple-elements in a list, you first need a function which gets the second element of a tuple, like 对于第一个函数,您可以重复该过程(如果您愿意,可以递归地):为了获取列表中的所有二元组元素,您首先需要一个函数来获取元组的第二个元素,如

getSecondElement :: (String, Int) -> Int
getSecondElement = undefined

and another function which applies that to all elements of a list. 以及将其应用于列表的所有元素的另一个函数。 I'll skip ahead a bit: the standard function for getting the second element of a 2-tuple is called snd , and the function for collecting the results of calling a function on all elements of a list is called map . 我将稍微先进一下:获取2元组的第二个元素的标准函数称为snd ,并且用于收集在列表的所有元素上调用函数的结果的函数称为map Try running 试试跑步

:t map snd

in ghci to see the type of map snd : 在ghci中查看map snd的类型:

map snd :: [(a, b)] -> [b]

...which is a generalized version of the type of our getSecondElements function! ...这是我们的getSecondElements函数类型的通用版本! So the two missing pieces are map snd and sum , which gives: 因此,两个缺失的部分是map sndsum ,它给出:

-- Takes a list of tuples and returns all the second elements
getSecondElements :: [(String, Int)] -> [Int]
getSecondElements someList = map snd someList

 -- Computes the sum of a given list of integers
sumOfIntList :: [Int] -> Int
sumOfIntList someInts = sum

Instead of having two extra functions, you can also define total in terms of map snd and sum directly: 您可以直接使用map sndsum定义total ,而不是使用两个额外的函数:

total someList = sum (map snd someList)

...which can be shortened to ......可以缩短为

total = sum . map snd

Not bad, is it? 不错,是吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Haskell:无法将预期类型“IO t0”与实际类型“[Char]”匹配 - Haskell: Couldn't match expected type ‘IO t0’ with actual type ‘[Char]’ Haskell:无法将预期类型“[a0]”与实际类型“([char], [int])”相匹配 - Haskell: Couldn't match expected type '[a0]' with actual type '([char], [int])' 无法将预期类型`Maybe(String,Int,String)&#39;与实际类型`([Char],t0,[Char])&#39;匹配 - Couldn't match expected type `Maybe (String, Int, String)' with actual type `([Char], t0, [Char])' 无法将预期类型“(t1,t2,t0)”与实际类型“ [a0]”匹配 - Couldn't match expected type `(t1, t2, t0)' with actual type `[a0]` Haskell无法将预期类型&#39;String&#39;与实际类型&#39;Char&#39;匹配 - Haskell Couldn't match expected type 'String' with actual type 'Char' Haskell“无法将预期类型“ a”与实际类型“ [a0]”匹配” - Haskell “Couldn't match expected type ‘a’ with actual type ‘[a0]’” Haskell 预期类型:[t0 a0] 实际类型:[a] - Haskell Expected type: [t0 a0] Actual type: [a] Haskell无法将预期类型[char]与实际类型IO匹配 - Haskell couldn't match expected type [char] with actual type IO Haskell:无法将预期的类型“ Tree Char”与实际类型“ Char-&gt; Tree Char”匹配 - Haskell: Couldn't match expected type ‘Tree Char’ with actual type ‘Char -> Tree Char’ Haskell类型错误“无法将类型“ Char”与“ t0 [Char]”匹配” - Haskell type error “Couldn't match type `Char' with `t0 [Char]'”
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM