View Full Version : [Help!] Haskell
Boas Pessoal eu sou novato nestas bandas da programaçao e estou aqui com um problema em haskell que é o seguint:
type Aluno = (Int, String, Float)
type Curso = [Aluno]
alunos :: Curso
alunos = [ (1234, "Jose Azevedo", 13.2), (2345, "Carlos Lopes", 9.7), (3456, "Rosa Mota", 17.9) ]
preciso agora de criar uma funçao que me de o nr d alunos reprovados e o nr d alunos aprovados eu tentei isto:
aAprovados :: [Aluno] -> [Int]
aAprovados [] = []
aAprovados ((x,y,z):zs) = if z >= 9.5
then 1
else z:(aAprovados zs)
mas nao resultou e tambem so calculava o nr d alunos aprovados e a funçao tem k calcular os 2:S
thnks e abraços ][
Boas Pessoal eu sou novato nestas bandas da programaçao e estou aqui com um problema em haskell que é o seguint:
type Aluno = (Int, String, Float)
type Curso = [Aluno]
alunos :: Curso
alunos = [ (1234, "Jose Azevedo", 13.2), (2345, "Carlos Lopes", 9.7), (3456, "Rosa Mota", 17.9) ]
preciso agora de criar uma funçao que me de o nr d alunos reprovados e o nr d alunos aprovados eu tentei isto:
aAprovados :: [Aluno] -> [Int]
aAprovados [] = []
aAprovados ((x,y,z):zs) = if z >= 9.5
then 1
else z:(aAprovados zs)
mas nao resultou e tambem so calculava o nr d alunos aprovados e a funçao tem k calcular os 2:S
thnks e abraços ][
func l = ( nr, ((length l) - nr))
where nr = length ([ z | (x,y,z) <- l, z > 9.5 ])
Rui_Carlos 24-10-2006, 00:59 para o caso de ainda não teres dado listas por compreensão...
ap_rep [] = (0,0)
ap_rep ((_,_,n):t) = let (ap,rep) = ap_rep t
in if n>=9.5 then (ap+1,rep)
else (ap,rep+1)
já agora, as tags 'code' existem para serem utilizadas...
para o caso de ainda não teres dado listas por compreensão...
ap_rep [] = (0,0)
ap_rep ((_,_,n):t) = let (ap,rep) = ap_rep t
in if n>=9.5 then (ap+1,rep)
else (ap,rep+1)
já agora, as tags 'code' existem para serem utilizadas...
para serem usadas por quem as quer usar.
o homem não queria um texto com tags code, queria uma função que lhe resolve-se o problema.
foi claramente isso que eu fiz.
Rui_Carlos 24-10-2006, 09:51 para serem usadas por quem as quer usar.
o homem não queria um texto com tags code, queria uma função que lhe resolve-se o problema.
foi claramente isso que eu fiz.
será que não se percebe melhor o código quando elas são usadas?
e se calhar a tua função não lhe resolve o problema pois falta um (ou mais) espaços antes do 'where' (que provavelmente até os colocaste mas como não usaste as tags foram eliminados).
para o caso de ainda não teres dado listas por compreensão...
ap_rep [] = (0,0)
ap_rep ((_,_,n):t) = let (ap,rep) = ap_rep t
in if n>=9.5 then (ap+1,rep)
else (ap,rep+1)
já agora, as tags 'code' existem para serem utilizadas...
txii isso ja é areia a mais para o meu camiao :S
podes explicar essa funçao sff?
1 amg meu cnsgui a definir 1 funçao para os aprovados, dp para os reprovados e juntou tudo numa outra funcao...
thnks
nunoalex 24-10-2006, 12:11 aAprovados :: [Aluno] -> Int
aAprovados [] = 0
aAprovados ((x,y,z):zs) = if z >= 9.5 then 1+aAprovados (zs)
else aAprovados zs
nAprovados :: [Aluno] -> Int
nAprovados [] = 0
nAprovados ((x,y,z):zs) = if z <= 9.5 then 1+nAprovados (zs)
else nAprovados zs
numero :: [Aluno] -> [Int]
numero [] = [0,0]
numero l = [ aAprovados l, nAprovados l]
isto e uma formula simples de fazer, calculas os aprovados e os nao aprovados e depois juntas numa funcao.... espero ter ajudado
Rui_Carlos 24-10-2006, 13:59 txii isso ja é areia a mais para o meu camiao :S
podes explicar essa funçao sff?
1 amg meu cnsgui a definir 1 funçao para os aprovados, dp para os reprovados e juntou tudo numa outra funcao...
thnks
ap_rep [] = (0,0) -- se a lista está vazia não há aprovados nem reprovados
ap_rep ((_,_,n):t) = let (ap,rep) = ap_rep t
-- se não está vazia calculamos o resultado para a cauda da lista e
-- colocamos o resultado no par (ap,rep)
in if n>=9.5 then (ap+1,rep)
else (ap,rep+1)
-- agora verificamos se a nota do aluno que está no topo da lista é ou não maior do que 9.5
-- se sim somamos 1 ao número de alunos aprovados que existem na cauda da lista
-- caso contrário somamos 1 ao número de alunos reprovados
mas a solução mais fácil de perceber é mesmo a do nunoalex (pois evita o uso do 'let...in')
thnks :)
eu normalmente defino 1º para o 1º elemento da lista e só depois para a cauda, ainda tenho que continuar a treinar haskell pa ver s cmço a encurtar as esquaçoes :s
obrigado a todos ][
O Haskell é tudo menos legivel...bolas...que raio de linguagem...
Rui_Carlos 25-10-2006, 00:02 O Haskell é tudo menos legivel...bolas...que raio de linguagem...
isso depende da forma como cada um programa.
a última versão em que está tudo separado acho que é bem legível (é claro que para quem está habituado a linguagens tipo C, não tem nada a ver).
isso depende da forma como cada um programa.
a última versão em que está tudo separado acho que é bem legível (é claro que para quem está habituado a linguagens tipo C, não tem nada a ver).
Parte do meu trabalho é programar, e muitas vezes trabalho em programas feitos por outras pessoas. Basicamente enquando que vocês tentam encurtar as formas, para mim quanto mais explicito estiver melhor :D.
A legibilidade num contexto empresarial é tremendamente importante, por vezes tão importante como a eficiencia do código.
Alguem me pode ajudar a defenir uma instancia da Class Read?
Nao sei os metodos que existem nesta classe.
Rui_Carlos 29-10-2006, 15:02 que tipo é que queres definir como instância da classe Read? tu não usaste nenhum data type.
definir as funções dessa classe é um pouco complicado... a forma mais fácil de resolver o problema é usar o 'deriving'.
data Exp o = Const Int | Var String | Op o [ Exp o ]
deriving Read
data Ops = Add | Mul | Sim
deriving Read
Apenas preciso de exemplos de como defeni-la, estes são dois dos DataTypes que estou a usar
Tenho mesmo de a fazer a mao para ter nota no trabalho
Fork também estou a fazer esse trabalho :P
Não arranjas ai um link fixe sobre transformadores de monads?
Rui_Carlos 30-10-2006, 00:16 data Exp o = Const Int | Var String | Op o [ Exp o ]
deriving Read
data Ops = Add | Mul | Sim
deriving Read
Apenas preciso de exemplos de como defeni-la, estes são dois dos DataTypes que estou a usar
Tenho mesmo de a fazer a mao para ter nota no trabalho
data Ops = Add | Mul | Sim deriving Show
instance Read Ops where
readsPrec _ r = [(str2ops x,t) | (x,t) <- lex r]
where str2ops "Add" = Add
str2ops "Mul" = Mul
str2ops "Sim" = Sim
data Exp o = Const Int | Var String | Op o [ Exp o ] deriving Show
instance (Read o) => Read (Exp o) where
readsPrec _ r=[(Const x,t)|("Const",r')<-lex r,(x,t)<-reads r']
++[(Var x,t)|("Var",r')<-lex r,(x,t)<-lex r']
++[(Op o x,t)
|("Op",r1)<-lex r
,(o,r2)<-reads r1
,(x,t)<-readList r2]
nunca tinha feito isto antes, como tal tive que procurar infomações na net sobre o assunto. deixo aqui alguns links que podem ser úteis:
http://lml.ls.fi.upm.es/~jjmoreno/prog_dec/haskell_EN_read_show.pdf
http://www.haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t%3ARead
http://www.zvon.org/other/haskell/Outputprelude/Read_c.html
http://www.mathematik.uni-marburg.de/~priebe/docs/mirror/tutorial/stdclasses.html
Fork também estou a fazer esse trabalho :P
Não arranjas ai um link fixe sobre transformadores de monads?
Também estou um bocado atrapalhado com o trabalho e precisava de umas dicas:P
Alguém me pode dizes como definiu (por exemplo) o func Add na instancia Opt Ops e como fez o push x:005:
thanks!!
Ando a rever o código todo, refiz agora o func Add para
func Add (x:y:t) = (x+y:t)
amanha volto com o push
Ando a rever o código todo, refiz agora o func Add para
func Add (x:y:t) = (x+y:t)
amanha volto com o push
Ja consegui fazer o func desta forma
func Add = \[x,y] -> x + y
visto que a aridade é 2...
O push é que ainda nada
Isso já tava definido no enunciado do trabalho lol
Isso já tava definido no enunciado do trabalho lol
yap... mas haskell nao é o meu forte e tava a ter algumas dificuldades em por akilo a funcionar...:lol:
Kuanto ao push penso que terá que ser com Monads de Estado >(. Alguma dica??
Tens de usar transformadores de monads para combinar as monads de estado e as monads de IO. Se não sabes o que isso é, tens de estudar porque também não te sei explicar.
1 faz a funçao a moda nao monadica
assim:
push :: Int -> Mem -> Mem
push x (Mem s h) = Mem (x:s) h
agora pra fazer á la monad wway fazes
pushST :: Int -> MemST
pushST x = get >>= put.push x
1 faz a funçao a moda nao monadica
assim:
push :: Int -> Mem -> Mem
push x (Mem s h) = Mem (x:s) h
agora pra fazer á la monad wway fazes
pushST :: Int -> MemST
pushST x = get >>= put.push x
obrigado fork... vou tentar fazer o resto... se puder ajudar em algo diz...
inté
1 faz a funçao a moda nao monadica
assim:
push :: Int -> Mem -> Mem
push x (Mem s h) = Mem (x:s) h
agora pra fazer á la monad wway fazes
pushST :: Int -> MemST
pushST x = get >>= put.push x
desculpa mas MemST... como definiste??
Em relação ás instancias da classe Read, pelo menos no meu código n funcionam.
Se com o código que puseram em cima fizerem por exemplo... um read (show (Const 4)) funciona ?
*Main> read("1+2") :: Exp Ops
(1+2)
http://www.techzonept.com/images/icons/icon10.gif
tens k fazer cast...
o meu grande problema é a leitura do tipo de dados Prog... http://www.techzonept.com/images/icons/icon14.gif
alg sabe cmo resolver erros de parse ambiguo sem recorrer a ferramentas externas ao haskell?
p.e.
*Main> read("-") :: Ops
*** Exception: Prelude.read: ambiguous parse
acrescentei ao data Ops = Add | Mul | Sim | Sub .. o símbolo é igual .. -.-
*Main> read("1+2") :: Exp Ops
(1+2)
http://www.techzonept.com/images/icons/icon10.gif
tens k fazer cast...
o meu grande problema é a leitura do tipo de dados Prog... http://www.techzonept.com/images/icons/icon14.gif
alg sabe cmo resolver erros de parse ambiguo sem recorrer a ferramentas externas ao haskell?
p.e.
*Main> read("-") :: Ops
*** Exception: Prelude.read: ambiguous parse
acrescentei ao data Ops = Add | Mul | Sim | Sub .. o símbolo é igual .. -.-
Remove o Sub, tas a defenir 2 operaçoes qom o mesmo sinal., assim nao da.
Para fazeres subtracçoes somas um nº comn o simetrico de outro
ya nem m tinhas lembrado dessa. de qq maneira continuo com a read a dar erros de ambiguidade ..
eu tenho a read a ler por listas de compreensao e qd leio :
*Main> read("2") :: Exp Ops
*** Exception: Prelude.read: ambiguous parse
*Main> read("a2") :: Exp Ops
*** Exception: Prelude.read: ambiguous parse
tenho qq coisa como isto :
ler x = [(Const i,y) | (i,y) <- reads x] ++ [(Var v,y) | (v,y) <- lex x, isAlpha $ head v]
percebe-se bem o pkê de estar ambiguo.. ag daí a resolver a ambiguidade vai um gd passo..
Kintela, usaste a instanciação para a read que o Ze Carlos meteu aqui? É que nem com cast funciona..
n . usei uma k ja tinha definido ja consegui resolver o problema da ambiguidade do parser.
vai ver isto
http://www.mathematik.uni-marburg.de/~priebe/docs/mirror/tutorial/stdclasses.html
ai tem um exemplo da read duma arvore.. eu fiz por comparacao a esse
por listas de compreensao.. só me falta ag meter a ler Prog Ops.. ja leio Ops e Exp Ops
para leres teras k fazer read (Const 2) :: Exp Ops .. i n show de read cmo tem aí postado em cima.
n precisas obrigatoriamente de usar as listas por compreensao .. podes construir a lista por recursividade.. eu só uso as funcoes reads e lex
|
|