View Full Version : [Help!] Haskell


Neo4
23-10-2006, 12:54
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 ][

mpLopes
24-10-2006, 00:46
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...

mpLopes
24-10-2006, 01:05
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).

Neo4
24-10-2006, 11:46
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')

Neo4
24-10-2006, 17:55
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 ][

AwakE
24-10-2006, 23:54
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).

AwakE
25-10-2006, 00:16
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.

Fork
29-10-2006, 14:14
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'.

Fork
29-10-2006, 15:06
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

jck
29-10-2006, 22:03
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

vctp
03-11-2006, 11:58
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!!

Fork
04-11-2006, 00:55
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

vctp
04-11-2006, 19:14
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

jck
04-11-2006, 22:35
Isso já tava definido no enunciado do trabalho lol

vctp
05-11-2006, 00:02
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??

jck
05-11-2006, 10:28
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.

Fork
05-11-2006, 19:57
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

vctp
05-11-2006, 23:24
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é

vctp
06-11-2006, 17:52
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??

jck
06-11-2006, 19:01
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 ?

kintela
11-11-2006, 06:30
*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 .. -.-

Fork
11-11-2006, 13:53
*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

kintela
11-11-2006, 14:58
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..

jck
11-11-2006, 19:59
Kintela, usaste a instanciação para a read que o Ze Carlos meteu aqui? É que nem com cast funciona..

kintela
11-11-2006, 20:11
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

kintela
11-11-2006, 21:03
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