簡體   English   中英

Haskell:使用int簽名整數到Int

[英]Haskell : Integer to Int with int signature

所以我遇到了一些變量類型的問題。

getOrdenado :: (String,Int,String,Int,Int) -> Int
getOrdenado (_,_,_,a,_) = a 

listaOrdenado :: [(String,Int,String,Int,Int)] -> [Int]
listaOrdenado xs = map getOrdenado xs

getOrdenado從元組列表中包含的元組中獲取某個Int值, listaOrdenado創建所有thoose特定Int的列表。

該函數應該在以下列表中起作用:

firma = [("Ana", 30, "RH", 1500, 3), ("Rui", 40, "Vendas", 1000, 2),
        ("Luis", 45, "RH", 3333, 5), ("Maria", 55, "Admin", 2000, 4)]

但每當我嘗試使用此列表運行listaOrdenado時 ,我會收到以下錯誤

Couldn't match type `Integer' with `Int'
Expected type: [(String, Int, String, Int, Int)]
  Actual type: [([Char], Integer, [Char], Integer, Integer)]
In the first argument of `listaOrdenado', namely `firma'
In the expression: listaOrdenado firma
In an equation for `it': it = listaOrdenado firma

我不允許在類簽名中使用Integer ,只允許Int,所以我不知道如何解決這個問題,也沒有任何線索為什么它說firma中的那些值是Integer

由於問題尚未解決,我編輯的答案更精確:

如果你的Haskell模塊中有頂級定義,Haskell將推斷出單態類型,而不是多態。 原因很簡單。 Haskell假設經常使用頂級定義,如果表達式具有單形類型,則必須僅對其進行求值。 在你的情況下,Haskell試圖為你的元組中的數字找到最合適的單態類型。 通過規范/實現,Haskell首先嘗試類型Integer ,然后嘗試類型Float 這就是您在代碼中出現類型錯誤的原因。

現在您有幾個選項可以解決此問題:

1.在模塊中添加firma類型(首選解決方案):

module Test where

getOrdenado :: (String,Int,String,Int,Int) -> Int
getOrdenado (_,_,_,a,_) = a 

listaOrdenado :: [(String,Int,String,Int,Int)] -> [Int]
listaOrdenado xs = map getOrdenado xs

firma :: Num a => [(String,a,String,a,a)]
firma = [("Ana", 30, "RH", 1500, 3), ("Rui", 40, "Vendas", 1000, 2),
        ("Luis", 45, "RH", 3333, 5), ("Maria", 55, "Admin", 2000, 4)]

如果你打電話給listaOrdenado firma ,它對我來說效果很好。

2.第二種可能性是通過覆蓋使用的默認值來關閉單態類型推斷。 如何完成此操作在此wiki條目中進行了解釋: https//wiki.haskell.org/Monomorphism_restriction

3.在我看來,最后但相當昂貴的解決方案是手動將列表中的元素強制轉換為首選類型。

如果您可以更改firma的簽名,只需為其添加適當的類型簽名:

firma :: [(String, Int, String, Int, Int)]
firma = [("Ana", 30, "RH", 1500, 3), ("Rui", 40, "Vendas", 1000, 2),
        ("Luis", 45, "RH", 3333, 5), ("Maria", 55, "Admin", 2000, 4)]

如果不允許更改firma ,可以通過在ghci提示符上為firma提供特定類型簽名來調用listaOrdenado

$ ghci firma.hs
λ> listaOrdenado (firma :: [(String, Int, String, Int, Int)])

如果firma實際上有一個使用了Integer的類型簽名,那么你需要使用fromIntegral以類似的方式從IntegerInt

fI = fromIntegral
integerToInt [] = []
integerToInt ((a,b,c,d,e):xs) = (a, fI b, c, fI d, fI e) : (integerToInt xs)

然后在ghci調用listaOrdenado

$ ghci firma.hs
λ> listaOrdenado (integerToInt firma)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM