开发者

Converting String to a user-defined type. Input-Output issue

Hello: I have a function which gets a string, and regarding what it gets, it calls some other functions. All but one of them, do not needs arguments. But t开发者_高级运维he one that do needs it expect to receive an argument which type is defined by me. My intention is to require input to pass. But, using getLine, getChar, getInt, store the input keeping the type ([Char],Char,etc), and I need to pass rough input to that function so the inferring system is able to detect that its type is my user-defined type (Fecha).

Extracts from code:

type Fecha = [(NombreJug,PuntosLogrados,MinutosJugados)]

armarListaDeTuplasPuntosFecha::Fecha->[(NombreJug,PuntosLogrados)]
armarListaDeTuplasPuntosFecha [] = []
armarListaDeTuplasPuntosFecha (ej:ejs) = [((\ (nombre,puntos,_)-> (nombre,puntos)) ej)] ++ armarListaDeTuplasPuntosFecha ejs


**jugadorConMayorCantidadDePuntoEnFecha unaFecha** = (\ (nombre,puntos)->nombre) (maximumBy mayorTupla (armarListaDeTuplasPuntosFecha unaFecha))

mejorJugadorPor::String->NombreJug
mejorJugadorPor criterio | criterio == "Mayor Cantidad de puntos en fecha" = do

                 fecha<-getLine                          
                 jugadorConMayorCantidadDePuntoEnFecha (fecha)
             | otherwise = "No es un criterio valido, reintente una proxima vez"

I would really appreciate if you can help me with this issue. The available documentation I've found its insufficient for me due to I'm a rookie with Haskell

Thank you very much in advance.

Regards


It looks like he is trying to keep track of players (NombreJug = player name), PuntosLogrados (points gained) and playing times (MinutosJugados) and then find the best player by some criteria.

armarListaDeTuplasPuntosFecha throws away the playing times to return a tuple of player name and points.

mejorJugadorPor ("Best player by") is trying to ask the user for a list of inputs and then select the player with the highest score. I think you are right that he needs a Read instance for his type, or a function to parse the input and turn it into type Fecha defined at the top. It also depends on how NombreJug,PuntosLogrados,MinutosJugados are defined. Are they type synonyms?

mejorJugadorPor also looks like it should be of type String-> IO NombreJug, since it performs IO actions.


This is my attempt to do what you want:

import Data.List

type NombreJug = String
type PuntosLogrados = Int
type MinutosJugados = Int

type Fecha = [(NombreJug,PuntosLogrados,MinutosJugados)]

armarListaDeTuplasPuntosFecha::Fecha->[(NombreJug,PuntosLogrados)]
armarListaDeTuplasPuntosFecha = map desechar
    where desechar (x,y,_) = (x,y)

jugadorConMayorCantidadDePuntoEnFecha unaFecha = fst (maximumBy mayorTupla (armarListaDeTuplasPuntosFecha unaFecha))

mayorTupla = undefined

mejorJugadorPor:: String -> IO NombreJug
mejorJugadorPor criterio 
    | criterio == "Mayor Cantidad de puntos en fecha" = do
                 fecha <- readLn                           
                 return $ jugadorConMayorCantidadDePuntoEnFecha fecha
    | otherwise = return "No es un criterio valido, reintente una proxima vez"

I added "mayorTupla = undefined" to get it to compile, because that function isn't defined in the code you posted.

Changes I made:

  1. your function armarListaDeTuplasPuntosFecha is better expressed with map. Map applies a function to every element of a list, which is what you are doing manually.

  2. jugadorConMayorCantidadDePuntoEnFecha can be expressed with fst, which returns the first element of a tuple of two values

  3. mejorJugadorPor needs to be in the IO monad because it performs input/output actions (reading something in that the user types). You do this by change the return type from String to IO String, to say that the return value depends on IO (ie the function isn't pure).

  4. The function readLn does what you want, because it converts the input string to the correct type as long as the type has an instance of Read. The Read type class basically means that you can convert a string into a value of the type somehow.

  5. Because mejorJugadorPor is monadic, you need to make sure that the value it returns is contained in the IO monad. This is what the function return does: it takes a value of type "a" and turns it into a value of type "m a", where m is any monad.


From what I could gather you want to make your Data types instances of the Read class and then use the read function to read string data into your datatypes.

If that was not what you had in mind let me know.


After several hours I got around the mess: with help from UK (Julian Porter: www.jpembedded.co.uk, www.porternet.org). Got the way not to create monads or modifying classes (I'm not at that level yet):

import Data.List

type NombreJug = String
type NombrePart = String
type Club = String
type Posicion = String
type Cotizacion = Integer
type PuntosLogrados = Integer
type MinutosJugados = Integer
type Jugador = (NombreJug,Club,Posicion,Cotizacion)
type Jugadores = [Jugador]
type PartConSusJug = (NombrePart,[NombreJug])
type Participantes = [PartConSusJug]
type Fecha = [(NombreJug,PuntosLogrados,MinutosJugados)]
type Fechas = [Fecha]

participantes = [("Natalia", ["Abbondazieri","Lluy","Battaglia", "Lazzaro"]),
                 ("Romina",  ["Islas", "Lluy", "Battaglia", "Lazzaro"]),
                 ("Jessica", ["Islas"])
                                      ]


clubes = ["Boca", "Racing", "Tigre"]


jugadores = [("Abbondazieri", "Boca", "Arquero", 6500000),
                ("Islas", "Tigre", "Arquero", 5500000),
                ("Lluy", "Racing", "Defensor", 1800000),
                ("Battaglia", "Boca", "Volante", 8000000),
                ("Lazzaro", "Tigre", "Delantero", 5200000),
            ("Monzon","Boca","Defensor",3500000),
            ("Guzman","Newells","Arquero",1000000),
            ("Diaz","Velez","Defensor",3600000),
            ("Palermo","Boca","Delantero",12000000),
            ("Aguirre","Lanus","Volante",4500000),
            ("Cura","Huracan","Defensor",1700000),
            ("Espinoza","Gimnasia","Volante",300000),
            ("Clemente","Deportivo Piraña","Volante",60000000)
                                         ]
miListaTuplasFechas = [("quinta",[("Lluy", 8, 90),("Lazzaro", 6, 90)]),("sexta",[("Lazzaro", 7, 77),("Islas", 6, 90),("Lluy", 7, 90)]),("septima",[("Battaglia", 13, 90), ("Lluy", 6, 90), ("Lazzaro", 8, 77)]),("octava",[("Islas", 4, 84), ("Battaglia", 8, 90)])] 


fechas = [quinta, sexta, septima, octava]


quinta  = [("Lluy", 8, 90), ("Lazzaro", 6, 90)]
sexta   = [("Lazzaro", 7, 77), ("Islas", 6, 90), ("Lluy", 7, 90)]
septima = [("Battaglia", 13, 90), ("Lluy", 6, 90), ("Lazzaro", 8, 77)]
octava  = [("Islas", 4, 84), ("Battaglia", 8, 90)]

-- 10)  mejorJugadorPor, recibe un criterio y devuelve el mejor jugador de acuerdo a ese criterio.
-- Dar además ejemplos de consultas que resuelvan los siguientes requerimientos:


mayorTupla (n1, c1) (n2, c2)
  | c1 > c2 = GT
  | c1 <= c2 = LT


-- 1.el jugador que logro mayor cantidad de puntos en todo el torneo. -> "Lazzaro"


armarListaDeTuplasPuntos::Jugadores->[(NombreJug,PuntosLogrados)]
armarListaDeTuplasPuntos [] = []
armarListaDeTuplasPuntos (ej:ejs) = [ (((\ (nombre,_,_,_)-> nombre) ej), (totalPuntosJugador ((\ (nombre,_,_,_)-> nombre) ej))) ] ++ armarListaDeTuplasPuntos ejs


mostrarmeLasTuplasPuntos = armarListaDeTuplasPuntos jugadores


jugadorConMayorCantidadDePuntosEnTorneo = (\ (nombre,puntos)->nombre) (maximumBy mayorTupla mostrarmeLasTuplasPuntos)


-- 2.el jugador que posee la mayor cotización.-> "Battaglia"


armarListaDeTuplasCotizacion::Jugadores->[(NombreJug,Cotizacion)]
armarListaDeTuplasCotizacion [] = []
armarListaDeTuplasCotizacion (ej:ejs) = [((\ (nombre,_,_,cotizacion)-> (nombre,cotizacion)) ej)] ++ armarListaDeTuplasCotizacion ejs


mostrarmeLasTuplasCotizaciones = armarListaDeTuplasCotizacion jugadores


jugadorConLaMayorCotizacion = (\ (nombre,cotizacion)->nombre) (maximumBy mayorTupla mostrarmeLasTuplasCotizaciones)
--Aquí se ve un ejemplo de aplicación de orden superior: la función maximumBy recibe dos funciones como agumentos.

-- 3.el jugador que logro mayor cantidad de puntos en una fecha. (en la 5º) -> "Lluy"


armarListaDeTuplasPuntosFecha::Fecha->[(NombreJug,PuntosLogrados)]
armarListaDeTuplasPuntosFecha [] = []
armarListaDeTuplasPuntosFecha (ej:ejs) = [((\ (nombre,puntos,_)-> (nombre,puntos)) ej)] ++ armarListaDeTuplasPuntosFecha ejs



jugadorConMayorCantidadDePuntoEnFecha [] = "Fecha no definida"
jugadorConMayorCantidadDePuntoEnFecha unaFecha = (\ (nombre,puntos)->nombre) (maximumBy mayorTupla (armarListaDeTuplasPuntosFecha unaFecha))


-- 4.el jugador que logro el mejor promedio en todo el torneo. ->  "Battaglia"


armarListaDeTuplasPromedios::Jugadores->[(NombreJug,Float)]
armarListaDeTuplasPromedios [] = []
armarListaDeTuplasPromedios (ej:ejs) = [ (((\ (nombre,_,_,_)-> nombre) ej), (promedioPuntosJugador ((\ (nombre,_,_,_)-> nombre) ej))) ] ++ armarListaDeTuplasPromedios ejs 


mostrarmeLasTuplasPromedios = armarListaDeTuplasPromedios jugadores


jugadorConMejorPromedioDelTorneo = (\ (nombre,puntos)->nombre) (maximumBy mayorTupla mostrarmeLasTuplasPromedios)
--Aquí se ve un ejemplo de aplicación de orden superior: la función mostrarmeLasTuplasPromerios es pasada como parámetro a la expresión lambda.


otroCaso = "No es un criterio valido, reintente una proxima vez"


listaDeCriterios criterio | (criterio == "jugadorConMayorCantidadDePuntosEnTorneo") = jugadorConMayorCantidadDePuntosEnTorneo
                  | (criterio == "jugadorConLaMayorCotizacion") = jugadorConLaMayorCotizacion
              | (criterio == "jugadorConMejorPromedioDelTorneo") = jugadorConMejorPromedioDelTorneo
                  | ((criterio /= "jugadorConMayorCantidadDePuntosEnTorneo")&& (criterio /= "jugadorConLaMayorCotizacion")&&(criterio /= "jugadorConMejorPromedioDelTorneo")) = otroCaso


devolverFecha::String->[(String,Fecha)]->Fecha
devolverFecha laFecha [] = []
devolverFecha laFecha (f:fs) | (((\ fechaIngresada (fechaAComparar,_)-> fechaIngresada == fechaAComparar) laFecha f) == True) = snd f
                 | otherwise = devolverFecha laFecha fs


criterios1 = do
   putStrLn "Ingrese la fecha deseada: "
   x<-getLine
   let resultado = ((jugadorConMayorCantidadDePuntoEnFecha (devolverFecha x miListaTuplasFechas)))
   putStrLn ("\""++resultado++"\"")


criterios2::String->IO ()
criterios2 criterio = do
   let resultado = (listaDeCriterios criterio)
   putStrLn ("\""++resultado++"\"")


eleccionDeCriterios criterioElegido | (criterioElegido == "jugadorConMayorCantidadDePuntoEnFecha") = criterios1
                            | otherwise = criterios2 criterioElegido


mejorJugadorPor = do
  putStrLn "Por favor, ingrese un criterio: "
  criterio<-getLine
  eleccionDeCriterios criterio

Console output:

Main> mejorJugadorPor
Por favor, ingrese un criterio: 
jugadorConMejorPromedioDelTorneo
"Battaglia"

Main> mejorJugadorPor
Por favor, ingrese un criterio: 
pepe
"No es un criterio valido, reintente una proxima vez"

Main> 
Main> 
Main> mejorJugadorPor
Por favor, ingrese un criterio: 
jugadorConMayorCantidadDePuntoEnFecha
Ingrese la fecha deseada: 
quinta
"Lluy"

Main> mejorJugadorPor
Por favor, ingrese un criterio: 
jugadorConMayorCantidadDePuntoEnFecha
Ingrese la fecha deseada: 
decima
"Fecha no definida"

It's in Spanish. If somebody finds it useful, contact me and I'll translate it into English.

Thank you very much for those who commented on this issue, and for their recommendations.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜