[英]infinite type error reversing a list in Haskell
我正在嘗試實現列表的反向:
myLast :: [a] -> a
myLast [] = error "No end for empty lists!"
myLast [x] = x
myLast (_:xs) = myLast xs
myReverse :: [a] -> [a]
myReverse (x:xs) = myLast xs + myReverse xs
但我收到此錯誤:
/workspaces/hask_exercises/exercises/src/Lib.hs:42:32: error:
* Occurs check: cannot construct the infinite type: a ~ [a]
* In the second argument of `(+)', namely `myReverse xs'
In the expression: myLast xs + myReverse xs
In an equation for `myReverse':
myReverse (x : xs) = myLast xs + myReverse xs
* Relevant bindings include
xs :: [a] (bound at src/Lib.hs:42:14)
x :: a (bound at src/Lib.hs:42:12)
myReverse :: [a] -> [a] (bound at src/Lib.hs:41:1)
|
42 | myReverse (x:xs) = myLast xs + myReverse xs
| ^^^^^^^^^^^^
cannot construct the infinite type: a ~ [a]
是什么意思? 我經常收到此錯誤,並想了解它的含義。
(+):: Num a => a -> a -> a
function 將兩個數字(相同類型)加在一起。 因此,例如,如果a ~ Int
,它將兩個Int
加在一起,但不是Int
和[Int]
。
但是,即使(+)
運算符例如將一個項目添加到列表中,它仍然無法正確反轉列表:您的 function 沒有基本情況如何處理空列表,並且您的遞歸列表與第一個無關列表中的項目x
(x:xs)
。
一個簡單的反轉方法:
myReverse :: [a] -> [a]
myReverse [] = []
myReverse (x:xs) = myReverse xs ++ [x]
但這效率不高:添加兩個項目將花費左列表大小的線性時間。 您可以使用累加器:每次進行遞歸調用時都會更新的參數。 這看起來像:
myReverse :: [a] -> [a]
myReverse [] = go []
where go ys (x:xs) = …
where go ys [] = …
填寫…
部分留作練習。
你有
myLast :: [a] -> a
myReverse :: [a] -> [a]
myReverse (x:xs) = myLast xs + myReverse xs
\___a___/ \____[a]___/
(x:xs) :: [a]
---------------
x :: a
xs :: [a] xs :: [a]
myLast :: [a] -> a myReverse :: [a] -> [a]
------------------------- ----------------------------
myLast xs :: a myReverse xs :: [a]
myReverse (x:xs) :: [a]
但
> :t (+)
(+) :: Num a => a -> a -> a
這意味着+
左邊的東西的類型和右邊的東西的類型必須相同。
但它們不可能是:正如我們剛剛在上面看到的,在您的代碼中,第一個( myLast xs
)是某種類型a
,第二個( myReverse xs
)是[a]
相同a
的列表。
這兩個不能相同,因為這意味着
a ~ [a] OK, this is given to us, then
a ~ [a] we can use it, so that
--------------
a ~ [[a]] this must hold;
a ~ [a] we know this, then
--------------
a ~ [[[a]]] this must also hold; and
a ~ [a] ........
-------------- ........
a ~ [[[[a]]]] ........
.........................
以此類推,無窮無盡,從而使其a
“無限”類型。 因此錯誤。
您可以通過將+
替換為
(+++) :: a -> [a] -> [a]
並實施它來做你需要它做的事情。
您還需要修復一個錯誤,即完全忽略接收到的輸入中的第一個元素x
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.