5

Here is my code:

type Niveles = (Int, Int, Int)
type Persona = (String, Niveles)    
type Pocion = (String, [(String, Int, [Efectos])])
type Ingredientes = [(String, Int, [Efectos])]
type Efectos = Niveles -> Niveles

aplicar3 f (a,b,c) = (f a, f b, f c)

invertir3 (a,b,c) = (c,b,a)

fst3 (a,_,_) = a
snd3 (_,b,_) = b
trd3 (_,_,c) = c

personas = [("Harry",(11, 5, 4)), ("Ron",(6,4,6)), ("Hermione",(8,12,2)), ("Draco",(7,9,6))]

f1 (ns,nc,nf) = (ns+1,nc+2,nf+3)
f2 = aplicar3 (max 7)
f3 (ns,nc,nf)
    | ns >= 8 = (ns,nc,nf+5)
    | otherwise = (ns,nc,nf-3)

misPociones :: [Pocion]
misPociones = [
    ("Felix Felices",[("Escarabajos Machacados",52,[f1,f2]),("Ojo de Tigre Sucio",2,[f3])]),
    ("Multijugos",[("Cuerno de Bicornio en Polvo",10, [invertir3, (\(a,b,c) -> (a,a,c))]),("Sanguijuela hormonal",54,[(aplicar3 (*2)), (\(a,b,c) -> (a,a,c)) ])]),
    ("Flores de Bach",[("Orquidea Salvaje",8,[f3]), ("Rosita",1,[f1])])]


efectosDePocion pocion = map trd3 (elementos pocion)

elementos :: Pocion -> Ingredientes
elementos (_, ingredientes) = ingredientes

I have a problem in the last piece of code, when I try to use the function "elementos":

elementos ("Felix Felices",[("Escarabajos Machacados",52,[f1,f2]),("Ojo de Tigre Sucio",2,[f3])])

I've got an error message:

<interactive>:311:1:
    No instance for (Show ((Int, Int, Int) -> (Int, Int, Int)))
      arising from a use of `print'
    Possible fix:
      add an instance declaration for
      (Show ((Int, Int, Int) -> (Int, Int, Int)))
    In a stmt of an interactive GHCi command: print it

Can someone explain this to me? How can I fix it?

TankorSmash
  • 12,186
  • 6
  • 68
  • 106
Margaery Tyrell
  • 53
  • 1
  • 1
  • 3

2 Answers2

13

In short, the function evaluates correctly - the problem is caused by evaluating it in ghci.

Your function call returns a value of type Ingredientes which is a type synonym for [(String, Int, [Efectos])]. ghci tries to print the returned value to the console, so it tries to call show on it. But Efectos is a type synonym for a function. ghci tells you that it doesn't know how to display a function, because it's not a member of the typeclass Show: No instance for (Show ((Int, Int, Int) -> (Int, Int, Int))).

It probably shouldn't concern you - you'd get a similar error by evaluating any function in ghci.

Benesh
  • 3,398
  • 1
  • 18
  • 38
5

Add to your .hs file the following code

instance Show (a -> b) where
         show a= "funcion"

Now ghci will be able to print "funcion" (function)

Good luck!

Charlyzzz
  • 590
  • 1
  • 4
  • 8
  • 1
    This piece of code works around the problem, but the answer by @Benesh is definitely more interesting - it tells us **why** this happens. – mgarciaisaia May 07 '14 at 03:50
  • 1
    Although this will solve the problem, *please* don't actually do this. It is an orphan instance, which is bad on it's own, but also throws out it's argument completey. This has the potential to break existing code. Other people may also not realize that this instance is in scope, and be surprised that the string "funcion" is showing up randomly. If you need this, then use `newtype Func a b = Func (a -> b)` or similar, and provide a seperate instance for Show. – Lazersmoke May 22 '17 at 15:48