2011-11-02 74 views
3

對於功能與類型簽名整數/ INT: 「Integer類型不匹配內部」

x :: Integer -> [a] -> [a] 
x = take 

y :: Integer -> [a] -> [a] 
y _ [] = [] 
y n xs = take n xs 

兩個擁抱和GHC報告類型錯誤:

ERROR "test.hs":5 - Type error in application 
*** Expression  : take n xs 
*** Term   : n 
*** Type   : Integer 
*** Does not match : Int 

ERROR "test.hs":8 - Type error in explicitly typed binding 
*** Term   : x 
*** Type   : Int -> [a] -> [a] 
*** Does not match : Integer -> [a] -> [a] 

這是由於這樣的事實「採取「有簽名」Int - > ...「。有沒有辦法告訴類型系統直接將Integer轉換爲Int(沒有fromIntegral),或者最好(保持Integer的非約束大小)來「構造」take的一個版本(或任何其他明確使用Int )爲整數?還是必須編寫我自己的Prelude-Functions版本?目前,我的代碼要麼來自整合(如果整數尺寸超過Int的尺寸,也不會運行),或者使用標準函數的簡單重新實現,並且感覺非常笨重。

回答

4

改爲使用Data.List中的genericTake。 「通用」列表函數接收Integer而不是Int。

在未來,如果你要搜索的類型簽名Haskell函數可以使用Hoogle


在更普遍的意義上說,如果你想要做的就是添加你可以使用一個轉換步驟內置的組合運算符可以輕鬆創建自己的功能。

--explicit type signature to force the less general types... 
integerToInt :: Integer -> Int 
integerToInt = fromIntegral 

myGenericTake = take . integerToInt 

--You can now use myGenericTake throughout the code. 
+0

只是一個例子。我仍然在學習Haskell,我試圖通過自己的方式來彌補我在大學裏所獲得的微薄教育,這就是我偶然發現的。 如果我想使用任何x :: Int - > ...與一個Integer,那是不可能的? (或者僅使用fromIntegral?) –

+0

@Max:添加了一些關於函數組合的信息。 – hugomg

+0

謝謝。最後一個問題: 我可以以任何方式告訴Haskell我希望它在遇到特定類型時使用Prelude函數(或任何函數)的實現嗎?我想用簽名take :: Integer - > ...編寫一個函數'take',然後讓Haskell在適當的時候選擇,以便我可以使用標準名稱而不是「myTake」或在我的代碼中「從整合」。 –

1

哈斯克爾需要的使任何隱式轉換的方法。因此,當您遇到像take這樣的功能時,您只需需要以使用fromIntegral或類似的方法執行顯式強制轉換。

如果那樣會讓你感到尷尬,那麼請表達你對改進Prelude的看法。你一定不會孤身一人,希望改進前奏功能。