Jump to content

[Resolvido] Duvida a calcular media


mundo
 Share

Recommended Posts

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

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

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

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.