Haskell,即使未指定我的类型,我也会收到此错误:无法匹配类型“a”;与“[a]”、“a”;是一个刚性类型变量,受以下约束

发布于 2024-12-15 03:27:28 字数 1031 浏览 2 评论 0原文

所以我意识到这可能是一个重复的问题,因为 Stack Overflow 上报告了许多此类错误,但没有一个解决方案似乎适用于我的问题。

所以我有以下函数:

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

如果你想知道这是99 Haskell Problems中的问题3。该函数的目标是将列表和索引作为输入,并返回该索引处的值(从 1 开始)。我不想要问题的解决方案,如果我想要,我可以只看提供的解决方案。但我收到一个我不明白的错误。我正在使用 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

在讨论此错误的所有线程中,我'我们已经研究过,当有人试图向需要某种类型的东西提供不正确的输出时,通常会发生这个问题。例如,将某些内容(Int 类型)的长度返回为“Num a”变量类型。

但就我而言,我什至没有提供变量 a 的类型。它应该可以是任何东西,对吧?那么为什么我会收到此错误?如果我明白为什么会出现错误,我可以修复它,但我就是不明白。

有人可以向我解释一下为什么我会收到此错误吗?

非常感谢您的帮助,谢谢。 -Asaf

编辑:到目前为止提供的每个答案都是正确的,谢谢大家提供的有用信息。我将选择我认为最清楚的一个(不过我必须等待 5 分钟才能完成)。

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.

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. 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). 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:

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.

But in my case I'm not even providing a type for variable 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

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).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

极致的悲 2024-12-22 03:27:28

输入不带类型声明的定义显示推断类型为 Integral b => [[a]]-> b->一个。没错,您当前的模式与列表列表匹配。

像这样的模式

f [pat] = ...

匹配一​​个单例列表,其唯一元素匹配pat。您想要使用 cons 又名 (:) 而不是要求一定的长度,然后您需要括号而不是方括号:

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

该错误基本上是说“您对待 a (第一个参数的元素),就像它是一个列表一样”。

Entering your definition without type declaration shows that the inferred type is 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. You want to work with cons a.k.a. (:) instead of requring a certain length, and then you need parenthesis instead of brackets:

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

The error basically says "you treat a (the elements of the first argument) as if it was a list".

东走西顾 2024-12-22 03:27:28

如果你想将列表匹配到头和尾,你应该使用

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

这是你需要的吗?

If you want to matching list to head and tail, you should use

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?

笑脸一如从前 2024-12-22 03:27:28

但就我而言,我什至没有提供变量 a 的类型。它应该可以是任何东西,对吧?

它必须能够是任何东西。根据您的类型签名,您的函数的用户必须能够使用 aInt 调用您的函数,a[Char] 或“a”是用户想要的任何其他内容。

然而,错误消息告诉您,您定义了函数,因此只能使用 a 作为某项列表来调用它。也就是说,您定义了它,因此第一个参数必须是列表的列表 - 它不能是其他任何内容的列表。这与你的类型签名相矛盾。

But in my case I'm not even providing a type for variable 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.

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. I.e. 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.

凡尘雨 2024-12-22 03:27:28

使用括号,而不是方括号:(x:xs)

module Aaa where

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

Use parentheses, not brackets: (x:xs)

module Aaa where

elementAt' (x:_) 1 = x
elementAt' (x:xs) y = elementAt' xs yminus1
    where yminus1 = y - 1
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文