Issues with data types


#1

Hello, i’m having a trouble where I need to create a function that uses data types that I created and I can’t understand the error that ghci throws
Here is my code:
data Carrera = Matematica | Fisica | Computacion | Astronomia | Profesorado
type Ingreso = Int
data Funcion = Teorico | Practico
data Rol = Decanx
| Docente Funcion
| Estudiante Carrera Ingreso
cuantos_doc :: [Rol] -> Funcion -> Int
cuantos_doc [] c = 0
cuantos_doc (x:xs) c =case f of
Docente c -> 1 + cuantos_doc xs c
otherwise -> cuantos_doc xs c
where f = x c

And here is the error

Proyecto2.hs:25:33: error:
• Couldn’t match expected type ‘Funcion -> t’
with actual type ‘Rol’
• The function ‘x’ is applied to one argument,
but its type ‘Rol’ has none
In the expression: x c
In an equation for ‘f’: f = x c
• Relevant bindings include f :: t (bound at Proyecto2.hs:25:29)
|
25 | where f = x c
| ^^^
Failed, no modules loaded.

I also tried using “case x c of…” and got this error

Proyecto2.hs:22:29: error:
• Couldn’t match expected type ‘Funcion -> Rol’
with actual type ‘Rol’
• The function ‘x’ is applied to one argument,
but its type ‘Rol’ has none
In the expression: x c
In the expression:
case x c of
Docente c -> 1 + cuantos_doc xs c
otherwise -> cuantos_doc xs c
|
22 | cuantos_doc (x:xs) c = case x c of
| ^^^
Failed, no modules loaded.

Thanks in advance


#2

Buenas Francisco,

The error is not related to the snipped you pasted (which loads
correctly in ghci), but to:

• Relevant bindings include f :: t (bound at Proyecto2.hs:25:29)
     >
  25 |                       where f = x c
     >                                 ^^^

No idea what x does, but as ghci suggests:

• The function ‘x’ is applied to one argument,
  but its type ‘Rol’ has none

x is not a function, so either change x or f.
Paste the relevant bit if you are still stuck!


#3

Hey, so x its an element of a list of Rol type elements. An execution example of cuantos_doc would be:

cuantos_doc [Decanx, Docente Teorico, Docente Practico] Teorico
1

I double checked that the error messages correspond to the code i pasted


#4

I should have waited for the edit!

This is correct, so why are you applying it to c in f = x c? x can’t be applied to anything, has zero arguments!
What are you trying to do with f? Can you write its signature?


#5

In a dumb desperate attempt to solve the problem I thought that maybe giving a variable (in this case f) instead of “x c” would do it.
What i’m attempting to do is something like

... x c == Docente c = 1 + ...

but i can’t use the Eq class and using filter is for the next exercise.


#6

x c is a function application, applying x to c won’t work in any case.

Be careful: the c in Docente c is not the same c in cuantos_doc (x:xs) c.

A working version could be:

data Carrera = Matematica | Fisica | Computacion | Astronomia | 
Profesorado  
type Ingreso = Int
data Funcion = Teorico | Practico deriving (Eq)
data Rol = Decanx
    | Docente Funcion
    | Estudiante Carrera Ingreso

cuantos_doc :: [Rol] -> Funcion -> Int
cuantos_doc []     c = 0
cuantos_doc (x:xs) c =
        case x of
          Docente k -> if k == c
                         then 1 + cuantos_doc xs c
                         else cuantos_doc xs c
          otherwise -> cuantos_doc xs c

Notice the deriving Eq.


#7

That’s exactly what I can’t use, must find another way to get the same result without using Eq


#8

Create a helper function that pattern matches on it:

miProfeEsTontoYNoMeDejaUsarAEq :: Funcion -> Funcion -> Bool
miProfeEsTontoYNoMeDejaUsarAEq Teorico  Teorico  = True
miProfeEsTontoYNoMeDejaUsarAEq Practico Practico = True
miProfeEsTontoYNoMeDejaUsarAEq _        _        = False

And then if miProfeEsTontoYNoMeDejaUsarAEq k c