Efficient way of printing property names in Haskell
Efficient way of printing property names in Haskell
Hello i am new to Haskell and i was wondering :
For every new defined type constructor even if it is something with 0 depth eg.:
data Letter =A | B | C deriving (Show)
do i have to provide
instance Show Type
Letter A = "A"
Letter B ="B"
Letter C ="C"
I understand that for nested types you have to provide Show
implementation but for something simple is there no other way to just use something equivalent to reflection (C#) ? Just get the property name / constructor name and ToString
-it ?
Show
ToString
Do haskell programmers provide instances for Show
for any adhoc type they create?
Show
By nested types i mean having a simple ADT inside another ADT inside another etc..but all you want is to get their names:
e.g:
data Person = Male | Female
data IsMarried=Yes | No
data Worker=Worker{
person::Person,
status::IsMarried
}
For this kind of nesting do i really have to define instance
of Show
for all these type constructors even though all i want is their name be "stringified"?
instance
Show
deriving Show
Show
If you add
deriving Show
the compiler writes the instance for you. Unless you want it to be different from the compiler's default, there's no need to write it on your own.– chi
Jun 29 at 11:32
deriving Show
2 Answers
2
Since @AJFarmar edit back his answer when i change it:
Do I have to provide [a show instance for every type?]
Yes. Either by deriving it with deriving Show
, or by supplying a type instance
deriving Show
instance Show -type- where...
instance Show -type- where...
I understand that for nested types you have to provide Show implementation[...]
Yes you do, the compiler will not add any necessary instances for Show.
data Test = Test -- no instance for Show
test :: String
test = show $ (Just Test :: Maybe Test)
Will not compile with the error message:
main.hs:4:8: error:
• No instance for (Show Test) arising from a use of ‘show’
• In the expression: show $ (Just Test :: Maybe Test)
In an equation for ‘test’: test = show $ (Just Test :: Maybe Test)
Which is why you need to have a Show
instance for a
aswell. If one already exists, you do not have to supply a new one, however.
Show
a
Do I have to provide [a show instance for every type?]
No, because you have automatically derived Show
:
Show
data Letter = A | B | C deriving (Show)
-- ^^^^^^^^^^^^^^^ Here
However, if you want a 'smarter' show
, such as displaying a custom list as [1,2,3]
rather than a mess of constructors, you're going to have to write it yourself.
show
[1,2,3]
You can do the same for a number of classes (Including Eq
,Ord
,Read
,Enum
, and Bounded
) but most classes, including user-defined classes, must be implemented manually without the use of certain language extensions.
Eq
Ord
Read
Enum
Bounded
I understand that for nested types you have to provide Show implementation[...]
You do not! For instance, I can write this:
data Maybe a = Just a | Nothing deriving (Show)
And the compiler will automatically add the necessary constraints, despite it being a 'nested' type.
Just get the property name / constructor name and ToString-it ?
There are no 'properties' in Haskell - don't think in terms of C# here. show
is the equivalent of ToString
. However, a form of type reflection is available in TypeReps, though I would advise not using this until you have a solid grasp on Haskell.
show
ToString
You can not magically derive
Show
for any polymorphic data type. The polymorphic types must also have instances of Show
.– Robert K
Jun 29 at 9:48
Show
Show
@RobertK Quote: "And the compiler will automatically add the necessary constraints." I'm fully aware the
a
in Maybe a
must also be an instance of Show
.– AJFarmar
Jun 29 at 9:53
a
Maybe a
Show
The compiler will not automatically add an instance of
Show
for a
. This is where i claim you are wrong.– Robert K
Jun 29 at 11:08
Show
a
@RobertK I suspect that what you mean by nested types is "types contained in another type", while what the original question asker meant was "types that contain another type". Perhaps this explains the confusion in the conversation thus far.
– Daniel Wagner
Jun 29 at 13:47
I am sorry for late response.For nested types i was meaning having ADT inside ADT. Something like
data Person=Male | Female
and data IsMarried=Yes | No
in data Worker=Worker{ type::Person , status::IsMarried}
.I didn't know if you have to provide show for each level of ADT even though you do not want any specific behaviour you just want the name of the data constructor toString
.– Bercovici Adrian
Jun 29 at 19:06
data Person=Male | Female
data IsMarried=Yes | No
data Worker=Worker{ type::Person , status::IsMarried}
toString
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
You have to instruct GHC how to render your type, yes. If you use
deriving Show
you do not need to provide an instance ofShow
.– Robert K
Jun 29 at 9:29