1
votes

I tried to define a show instance for an ADT, but I get the error Argument list lengths differ in declaration show. How can I make this work without using Generic?

data Route = Home | Users String | User Int | NotFound String

instance showRoute :: Show Route where
    show Home = "Home"
    show Users str = "Users"
    show User i = "User"
    show NotFound str = "404"
1

1 Answers

4
votes

You have to wrap constructors with arguments in parenthesis. Try something like this:

instance showRoute :: Show Route where
  show Home = "Home"
  show (Users str) = "Users"
  show (User i) = "User"
  show (NotFound str) = "404"

Show RELATED SIDE NOTE:

You can also derive Show instance for such a simple type using purescript-generic-reps, but you have to derive instance for Generic first:

import Data.Generic.Rep (class Generic)
import Data.Generic.Rep.Show (genericShow)

data Route = Home | Users String | User Int | NotFound String
derive instance genericRoute :: Generic Route _

instance showRoute :: Show Route where
  show = genericShow

I've made simple snippet so you can play with it on try.purescript.org

It's even possible to mix these two approaches:

instance showRoute :: Show Route where
  show (Users u) = "CusomUsersShow " <> u
  show u = genericShow u

For debugging purposes you can always use traceAny (traceAnyA, spy, etc.) from purescript-debug. Personally I'm writing Show instances only when I have to (forced for example by purescript-test-unit).