2015-10-29 3 views
2

Так что у меня проблемы с некоторыми переменными типами.Haskell: Integer to Int с 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 

Я не разрешено используйте Целое число в подписи класса, только Int, так что я не знаю, как это решить, и у меня нет cl у.е, почему он говорит, что эти ценности в ФИРМЫ являются Integer «s

+0

Вы можете принудительно ввести 'Int' в качестве типа, введя такие встроенные типы, как' 30 :: Int', или дайте 'firma' подпись типа, чтобы вместо' Integer' вместо 'Integer' использоваться' Int'' default) – KarlC

+1

Попробуйте положить 'firma :: [(String, Int, String, Int, Int)]' перед объявлением для 'firma'. Если вы определяете это в GHCi, тогда вместо этого помещайте его в файл. – bheklilr

+0

Мне не разрешено давать какие-либо подписи ** firma **, более конкретно мне не разрешено ничего менять о ** firma ** – eXistanCe

ответ

4

Поскольку проблема еще не решена, я уточнил, что мой ответ будет более точным:

Если у вас есть определения верхнего уровня в вашем модуле Haskell, Haskell выберет мономорфный тип, а не полиморфный. Причина очень проста. Хаскелл предполагает, что определение верхнего уровня используется довольно часто, и если выражение имеет мономорфный тип, оно должно оцениваться только одним. В вашем случае Haskell пытается найти подходящий тип monomorphic для чисел в вашем кортеже. По спецификации/реализации Haskell сначала пробует тип Integer, а затем тип Float. Вот почему у вас есть ошибка типа в коде.

Теперь у вас есть несколько вариантов решения этой проблемы:

1.Добавить тип ФИРМЫ в модуле (предпочтительно раствор):

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. Вторая возможность - отключить вывод мономорфного типа, заменив используемые значения по умолчанию. Как это делается, объясняется в этой вики-записи: https://wiki.haskell.org/Monomorphism_restriction

3. Последнее, но довольно дорогое решение, на мой взгляд, - это вручную отнести элементы вашего списка к предпочитаемому типу.

+0

Аннотирование на используемом сайте приведет только к перемещению типа ошибки. – dfeuer

+0

После добавления этой строки к моему коду: firma :: Num a, Num b, Num c => [(String, a, String, b, c)] При попытке загрузить мой .hs-файл я получаю следующую ошибку на ghci: .hs: 1: 15: ошибка синтаксического анализа на входе ', ' caracter 15 является первым, после ** a ** – eXistanCe

+0

извините, это была ошибка копирования, я обновил свой ответ. – siebenschlaefer

2

Если вы можете изменить подпись 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, вы можете вызвать listaOrdenado давая firma конкретный тип подписи на ghci строке:

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

Если firma на самом деле имеет сигнатуру типа с Integer используется, то вам нужно отливать из Integer в Int используя fromIntegral каким-то образом, как это:

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

и затем вызвать listaOrdenado как это в ghci:

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

Вещь firma - это список, который будет использоваться для проверки моего кода, у фирмы может быть больше кортежей, чем те, которые мне предоставили, единственная твердая вещь - это типы переменных внутри кортежей. Поэтому я не могу поместить в версию версию firma. Hs, и я не могу добавить спецификацию при вызове ее для ghci, так как я не буду ее звать при оценке функций. и я действительно верю, что фирма не имеет подписи или, по крайней мере, мне не предоставляется. – eXistanCe

+0

Если вы не являетесь тем, кто вызывает 'listaOrdenado', и вам не разрешено использовать' Integer' или 'Num' в типе подпись, то вы можете просто предположить, что кто-то, кто использует ваш код, пройдет в нужном типе, потому что на вызывающем абоненте присутствует нужный тип, потому что Haskell строго типизирован. – KarlC