Haskell:使用int签名整数到Int

eXi*_*nCe 3 int haskell integer type-conversion

所以我遇到了一些变量类型的问题.

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

listaOrdenado :: [(String,Int,String,Int,Int)] -> [Int]
listaOrdenado xs = map getOrdenado xs
Run Code Online (Sandbox Code Playgroud)

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)]
Run Code Online (Sandbox Code Playgroud)

但每当我尝试使用此列表运行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
Run Code Online (Sandbox Code Playgroud)

我不允许在类签名中使用Integer,只允许Int,所以我不知道如何解决这个问题,也没有任何线索为什么它说firma中的那些值是Integer

sie*_*fer 5

由于问题尚未解决,我编辑的答案更精确:

如果你的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)]
Run Code Online (Sandbox Code Playgroud)

如果你打电话listaOrdenado firma,它对我来说很好.

2.第二种可能性是通过覆盖使用的默认值来关闭单态类型推断.如何完成此操作在此wiki条目中进行了解释:https://wiki.haskell.org/Monomorphism_restriction

3.在我看来,最后但相当昂贵的解决方案是手动将列表中的元素强制转换为首选类型.