简体   繁体   English

Haskell-应用程序中的类型错误

[英]Haskell - Type error in application

I have a problem writing a Haskell function. 我在编写Haskell函数时遇到问题。 The compiler says: 编译器说:

Type error in application 应用程序中输入错误

Expression : move (offset - 1) (saveList subList (x : xs)) xs 表达式:move(offset-1)(saveList subList(x:xs))xs

test :: Int -> [Int] -> [Int]
test _ [] = []
test offset (xs) = move offset [] xs
                   where
                       move offset subList (x:xs) | offset == 0 = subList ++ rotate (last (x:xs)) (x:xs)
                                                  | otherwise   = move (offset-1) (saveList subList (x:xs)) xs

                       saveList save (x:xs) = save ++ [x]

                       rotate _ [] = []
                       rotate item (x:xs) = item : (move x xs)

                       last (x:[]) = x
                       last (x:xs) = last xs

But I can't see any mistake. 但是我看不到任何错误。 What did I do wrong? 我做错了什么?

It looks like move is supposed to be a function of three arguments, but in rotate you use it like this: item : (move x xs) . 看起来move应该是三个参数的函数,但是在rotate您可以这样使用它: item : (move x xs)

In Haskell, move x xs is a valid value (it's the function obtained by currying move twice, first with x and then with xs ), but it doesn't seem like what you want here. 在Haskell中, move x xs是一个有效值(这是通过先两次move一次,再使用x然后再使用xs两次两次move获得的函数),但这似乎不是您想要的。

When you get a confusing error message, it often helps to clarify what you mean to the compiler by adding type signatures. 当您收到一个令人困惑的错误消息时,通常可以通过添加类型签名来帮助您阐明对编译器的含义。 I added type signatures to your code like this: 我将类型签名添加到您的代码中,如下所示:

move :: Int -> [Int] -> [Int] -> [Int]
saveList :: [Int] -> [Int] -> [Int]
rotate :: Int -> [Int] -> [Int]
last :: [Int] -> Int

GHCI then gives me the following error message, which is much more helpful about where the actual problem is: GHCI然后给我以下错误消息,这对于实际问题出在哪里更有帮助:

foo.hs:14:52:
    Couldn't match expected type `[Int]'
           against inferred type `[Int] -> [Int]'
    In the second argument of `(:)', namely `(move x xs)'
    In the expression: item : (move x xs)
    In the definition of `rotate':
        rotate item (x : xs) = item : (move x xs)

This error message says quite plainly that when reading (move x xs) on line 14, GHCI expected to find something of type [Int] (a list of integers), but actually found something of type [Int] -> [Int] (a function taking a list of integers and returning a list of integers). 该错误消息非常清楚地表明,在第14行读取(move x xs)时,GHCI期望找到类型为[Int] (整数列表)的东西,但实际上找到了类型为[Int] -> [Int] (接受整数列表并返回整数列表的函数)。

First of all, the function last exists already in Prelude , so you don't need to define it yourself. 首先, last函数已经存在于Prelude ,因此您无需自己定义它。 Secondly, please use spaces instead of tabs. 其次,请使用空格而不是制表符。 This is about the 5th time I've said this on SO this week. 这是本周我在SO上第五次这样说。 Haskell will work with tabs, but it ends up causing problems because in your editor blocks look lined up, but the parser doesn't always see it that way. Haskell可以使用选项卡,但是最终会导致问题,因为在您的编辑器块中看起来是对齐的,但是解析器并不总是以这种方式看到它。 It also messes up formatting when you copy/paste into stackoverflow. 当您将复制/粘贴到stackoverflow中时,它还会弄乱格式。

The problem I found was actually in the definition for rotate : 我发现的问题实际上是在rotate的定义中:

rotate item (x:xs) = item : move x xs

Here, you're only providing 2 of 3 arguments to move , so you're getting a type error. 在这里,您仅提供3个参数中的2个作为move ,所以您遇到类型错误。 I got it to compile with 我可以编译

rotate item (x:xs) = item : move x [] xs

But I don't know if that you're desired behavior. 但是我不知道你是否是想要的行为。

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

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