简体   繁体   English

Haskell,即使我的类型未指定,我也会收到此错误:无法将类型“a”与“[a]”匹配,“a”是绑定的刚性类型变量

[英]Haskell, Even though my type is not specified I get this error: Couldn't match type `a' with `[a]', `a' is a rigid type variable bound by

So I realize this is a possible duplicate question, as there a number of those errors reported on Stack Overflow, but none of the solutions seem to apply to my problem. 所以我意识到这是一个可能重复的问题,因为在Stack Overflow上报告了许多错误,但没有一个解决方案似乎适用于我的问题。

So I have the following function: 所以我有以下功能:

elementAt' :: Integral b => [a] -> b -> a
elementAt' [x:_] 1 = x
elementAt' [x:xs] y = elementAt' xs yminus1
    where yminus1 = y - 1

In case you're wondering it's problem 3 from 99 Haskell Problems . 如果您想知道99 Haskell问题中的问题3。 The goal of the function is to take as input a list and an index, and return the value at that index (starting at 1). 该函数的目标是将列表和索引作为输入,并返回该索引处的值(从1开始)。 I don't want a solution to the problem, if I did I could just look at the ones provided. 我不想解决这个问题,如果我这样做,我可以看看提供的解决方案。 But I'm getting an error I don't understand. 但我收到一个我不明白的错误。 I'm using eclipseFP, the eclipse plugin for haskell and it's underlining the "[x:_]" and "[x:xs]" portions of the function with the following error: 我正在使用eclipseFP,它是haskell的eclipse插件,它强调了函数的“[x:_]”和“[x:xs]”部分,并出现以下错误:

Couldn't match type `a' with `[a]'
`a' is a rigid type variable bound by
the type signature for elementAt' :: Integral b => [a] -> b -> a

In all the threads that discuss this error that I've looked at the problem usually occurs when someone tries to give an incorrect output to something which expects a certain type. 在讨论这个错误的所有线程中,我已经看到问题通常发生在有人试图将错误的输出提供给需要某种类型的东西时。 For example, returning the length of something (which is of type Int) to what should be a "Num a" variable type. 例如,将某些东西(Int类型)的长度返回到应该是“Num a”变量类型的长度。

But in my case I'm not even providing a type for variable a. 但在我的情况下,我甚至没有提供变量a的类型。 It should be able to be ANYTHING, right? 它应该可以是任何东西,对吧? So why am I getting this error? 那我为什么会收到这个错误呢? If I understood why I was getting the error I could fix it, but I just don't understand. 如果我理解为什么我得到错误我可以解决它,但我只是不明白。

Could someone please explain to me why I'm receiving this error? 有人可以向我解释为什么我收到这个错误?

Your help is much appreciated, thank you. 非常感谢您的帮助,谢谢。 -Asaf -Asaf

Edit: Every answer provided so far is correct, thank you all for the helpful information. 编辑:到目前为止提供的每个答案都是正确的,谢谢大家提供的有用信息。 I'm going to pick the one I believe to be most clear (I have to wait 5 minutes to do it though). 我要选择一个我认为最清楚的那个(我必须等5分钟才能完成)。

Entering your definition without type declaration shows that the inferred type is Integral b => [[a]] -> b -> a . 输入没有类型声明的定义表明推断类型是Integral b => [[a]] -> b -> a That's correct, your current patterns match lists of lists. 这是正确的,您当前的模式匹配列表列表。

A pattern like 像一个模式

f [pat] = ...

matches a singleton list whose sole element matches pat . 匹配其唯一元素匹配pat的单例列表。 You want to work with cons aka (:) instead of requring a certain length, and then you need parenthesis instead of brackets: 你想使用cons aka (:)而不是需要一定的长度,然后你需要括号而不是括号:

elementAt' (x:xs) n = ...

The error basically says "you treat a (the elements of the first argument) as if it was a list". 错误基本上说“你把a (第一个参数的元素),如果它是一个列表”。

If you want to matching list to head and tail, you should use 如果你想将列表匹配到head和tail,你应该使用

elementAt' (x:_) 1 = x

So, finally 所以,最后

elementAt' :: Integral b => [a] -> b -> a
elementAt' (x:_) 1 = x
elementAt' (x:xs) y = elementAt' xs yminus1
    where yminus1 = y - 1

And

λ> elementAt' [1,2,3] 2
2

Is it what you need? 这是你需要的吗?

But in my case I'm not even providing a type for variable a. 但在我的情况下,我甚至没有提供变量a的类型。 It should be able to be ANYTHING, right? 它应该可以是任何东西,对吧?

It has to be able to be anything. 它必须能够成为任何东西。 According to your type signature the user of your function has to be able to call your function with a being Int , with a being [Char] or with `a´ being whatever else the user wants to. 根据您的类型签名的功能,用户必须能够调用你的函数与aInt ,用a幸福[Char]或'其他任何用户想要A'的存在。

However the error message is telling you that you defined your function so that it's only possible to call it with a being a list of something. 然而,错误信息告诉你,所以,它是唯一可能与调用它,你定义你的功能a是东西的清单。 Ie you defined it, so that the first argument has to be a list of lists - it can't be a list of anything else. 即你定义它,所以第一个参数必须是列表列表 - 它不能是其他任何列表。 And that contradicts your type signature. 这与你的类型签名相矛盾。

Use parentheses, not brackets: (x:xs) 使用括号,而不是括号: (x:xs)

module Aaa where

elementAt' (x:_) 1 = x
elementAt' (x:xs) y = elementAt' xs yminus1
    where yminus1 = y - 1

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM