mundo Posted October 25, 2011 at 06:23 PM Report Share #417499 Posted October 25, 2011 at 06:23 PM Boas, estou com um problema, preciso de calcular a media final com que acaba uma Turma, possuo o seguinte codigo, nao vejo o que está mal, gostava de saber se me podem ajudar com isto, sugestões, é tudo bem vindo. type Aluno = (Numero, Nome, ParteI, ParteII) type Numero = Int type Nome = String type ParteI = Float type ParteII = Float type Turma = [Aluno] notasFinais :: Turma -> [Float] notasFinais t = notasF (passaram t) notasF :: Turma -> [Float] notasF [] = [] notasF ((_,_,np1,np2):t) = (np1+np2) : (notasF t) --d) mediaNotas :: [Float] -> Float mediaNotas [] = 0.0 mediaNotas (x:xs) = sum (x:xs) / length (x:xs) Link to comment Share on other sites More sharing options...
Rui Carlos Posted October 25, 2011 at 07:04 PM Report Share #417504 Posted October 25, 2011 at 07:04 PM Qual é o problema/erro da versão desse código? Rui Carlos Gonçalves Link to comment Share on other sites More sharing options...
mundo Posted October 25, 2011 at 07:08 PM Author Report Share #417507 Posted October 25, 2011 at 07:08 PM Eu penso que esteja correcto, tipo eu quero somar uma lista dai ter sum (x:xs) e faço o length(x:xs) para obter o tamanho da lista, pois o calculo da media e feito pela soma aritmetica a dividir pelo numero de parcelas como todos sabem lol. o compilador queixa-se do seguinte: Couldn't match expected type `Float' with actual type `Int' In the return type of a call of `length' In the second argument of `(/)', namely `length (x : xs)' In the expression: sum (x : xs) / length (x : xs) Link to comment Share on other sites More sharing options...
Baderous Posted October 25, 2011 at 08:54 PM Report Share #417518 Posted October 25, 2011 at 08:54 PM Tens de fazer a conversão do Int que resulta da função length: mediaNotas :: [Float] -> Float mediaNotas [] = 0.0 mediaNotas l = (sum l) / (fromIntegral $ length l) Link to comment Share on other sites More sharing options...
mundo Posted October 25, 2011 at 09:05 PM Author Report Share #417522 Posted October 25, 2011 at 09:05 PM Hum acho que percebi, é necessario um cast pois o length só lê int's nao e baderous?, mas tipo o sum supostamente e de uma lista, ao tarmos a declarar l, deixa de ser lista certo? Link to comment Share on other sites More sharing options...
Baderous Posted October 25, 2011 at 09:53 PM Report Share #417538 Posted October 25, 2011 at 09:53 PM Hum acho que percebi, é necessario um cast pois o length só lê int's nao e baderous? Não. O length devolve um Int que é o comprimento (nº de elementos) de uma lista, seja ela do que for (inteiros, floats, strings, etc). length :: [a] -> Int Estás a usar a divisão real (/), que é uma função da classe Fractional: :i Fractional (/) :: a -> a -> a :t (/) (/) :: (Fractional a) => a -> a -> a O que obriga a que ambos os argumentos da função sejam do tipo Fractional. Mas o que tens é o resultado da função sum e da length: sum :: (Num a) => [a] -> a length :: [a] -> Int O resultado da sum é um tipo que é instância da classe Num. A classe Num é superclasse de Fractional, como podes ver: class (Num a) => Fractional a where Portanto, o único problema a resolver é o da função length, porque há uma incompatibilidade de tipos (Int - Fractional). A função fromIntegral tem o seguinte tipo: fromIntegral :: (Integral a, Num b) => a -> b Dado um argumento que é um Integral, devolve como resultado um Num (que é aquilo que é preciso). Mas Int é diferente de Integral, são 2 classes diferentes. No entanto, Int é instância da classe Integral: :i Int ... instance Integral Int -- Defined in GHC.Real ... Logo, ao aplicar a função fromIntegral sobre o resultado da length, vais transformar um Int (que é um Integral também) num Num e os tipos vão bater certo, daí que já possas aplicar a divisão real aos valores pretendidos. mas tipo o sum supostamente e de uma lista, ao tarmos a declarar l, deixa de ser lista certo? l é o nome que dás à lista, tanto podes ter lá l como (x:xs) como tinhas, mas como para a definição da função não precisas de trabalhar especificamente com a cabeça e cauda da lista, não é preciso usar essa forma. Penso que não me enganei nalguma coisa da explicação, já não mexo em Haskell há algum tempo, mas penso que no geral é isso. Link to comment Share on other sites More sharing options...
mundo Posted October 26, 2011 at 09:48 AM Author Report Share #417590 Posted October 26, 2011 at 09:48 AM Fiquei totalmente esclarecido, obrigado pela dica e pela explicação. Podem fechar ::rox:: 🙂 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now