Efficient way of printing property names in Haskell - 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 ?
Do haskell programmers provide instances for Show for any adhoc type they create?
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"?

Do I have to provide [a show instance for every type?]
No, because you have automatically derived 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.
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.
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.

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
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.

Related

Creating a typeclass in Haskell but getting "ambiguos occurence" error

I'm new to Haskell and currently trying to figure out how to write my own typeclasses. This is what I've got so far:
data Signal = X | O
class Show a where
show :: a -> String
instance Show Signal where
show X = "X"
show O = "O"
And when I try this out I get an error :
Ambiguous occurrence `Show'
It could refer to
either `Prelude.Show',
or `Main.Show
And I can't figure out why that is because I thought the whole point of typeclasses in Haskell was that it made overloading of functions possible? Thanks in advance for your help!
And I can't figure out why that is because I thought the whole point of typeclasses in Haskell was that it made overloading of functions possible?
That is correct, but you here define a new typeclass Show that is clashing with the one in the Prelude.
If you define an instance, then it is ambiguous to which Show typeclass it is referring. To the one defined in the Prelude (where al lot of types are members of), or the one you defined in your own program.
You thus can define this as:
data Signal = X | O
-- no definition for Show
instance Show Signal where
show X = "X"
show O = "O"
If you want to define your own typeclass, you can work with:
import Prelude hiding (Show)
data Signal = X | O
class Show a where
show :: a -> String
instance Show Signal where
show X = "X"
show O = "O"
but that is probably not a good idea, since all the other types are no member of the new typeclass, only a member of the one defined in the Prelude.
A typeclass can thus be seen as an interface in languages like Java: your data types can be members of a typeclass if they define an instance that thus defines the implementation of the methods (here show). But if two interfaces have the same name, that does not mean that these are the same interface.

Interaction of multiple overlapping instances

The module Type.hs defines the homonym newtype and exports only its type constructor, but not the value constructor, to avoid exposing the detail; it also provides a constructor function makeType to balance the lack of value ctor. Why do I need to wrap a String in a new type? Because I want it to be more than a String; in my specific case, Type is actually called Line, and what corresponds to makeType enforces that it contains only one \n, as the last character. A newtype seemed the most obvious choice to me. If this is not the case, forgive me: I'm learning.
module Type (Type, makeType) where
newtype Type = Type String
makeType :: String -> Type
makeType = Type
In order to show a value of type Type the way I like (for instance, given my actual usecase of Line, I might want to represent \n with a nice unicode character, or with the sequence <NL>, or whatever), I created another module TypeShow.hs, which I later (in the attempt of doing what I'm describing) I edited by adding some pragmas. Why another module? Because I guess the way something works inside and the way I show it to screen are two separete aspects. Am I wrong?
{-# LANGUAGE FlexibleInstances #-}
module TypeShow () where
import Type
instance Show Type where
show = const "Type"
-- the following instance came later, see below why
instance {-# OVERLAPS #-} Show (Maybe Type) where
show (Just t) = show t
show _ = ""
Beside this pair of modules (which describe the core of Type, and how it should be shown), I created other similar pairs Type1/Type1Show, Type2/Type2Show, which all wrap a String to represent and show other String-like entities.
For other reasons, I also needed another type which wraps an optional value, which can be of type Type, Type1, or any other type, so I wrote this module
module Wrapper (Wrapper, makeWrapper, getInside) where
newtype Wrapper a = Wrapper { getInside :: Maybe a }
makeWrapper :: a -> Wrapper a
makeWrapper = Wrapper . Just
(In reality Wrapper actually wraps more than one Type value, but I'll avoid putting more details then necessary; if the following is stupid exactly because I'm wrapping only one Type value in Wrapper, then please consider it's wrapping more than one, in reality.) Again, here I tried to hide the details of Wrapper while providing makeWrapper to make one, and getInside to have a "controlled" access to its inside.
I also wanted to show this on screen, so I created a corresponding WrapperShow.hs module, so that Wrapper's show method relies on the content's show method.
module WrapperShow () where
import Wrapper
instance Show a => Show (Wrapper a) where
show = show . getInside
At this point, however, when the type a is a Maybe Type, I wanted to show the content of the Wrapper printing an empty string instead of Nothing, or the content of the Just; therefore I wrote the instance Show (Maybe Type) that I commented above.
Given this, Type "hello" and Just $ Type "hello" are both correcly shown as Type, but Wrapper $ Just $ Type "hello" is displayed as Just Type, just like it's using Maybe's original instance of Show, irrespective of the fact that for this specific type inside the Maybe (the Type) I've customized the Show instance.
In the Show instance declaration for Wrapper, we don't really know what a is. But apparently we must already choose what Show instance to use for the Maybe a. With the information available, the only instance that matches is the default one Show a => Show (Maybe a), which doesn't require a concrete a.
The GHC User Guide, in the section about overlapping instances, mentions the concept of "postponing" the choice of an instance:
That postpones the question of which instance to pick to the call site
for f by which time more is known about the type b. You can write this
type signature yourself if you use the FlexibleContexts extension.
and
Exactly the same situation can arise in instance declarations themselves [...] The solution is to postpone the choice by adding the constraint to the context of the instance declaration
We could try such a trick. Instead of requiring Show a, require the whole Show (Maybe a). Now the Show instance is taken as "given" and we don't make a local decision. I think this has the effect of delaying the selection of the Show (Maybe a) instance to call sites like print $ Wrapper $ Just $ Type 3, where we have more information about the concrete type of a.
Testing this hypothesis:
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE UndecidableInstances #-}
newtype Type = Type Int
instance Show Type where
show = const "Type"
instance {-# OVERLAPS #-} Show (Maybe Type) where
show (Just t) = show t
show _ = ""
newtype Wrapper a = Wrapper (Maybe a)
instance Show (Maybe a) => Show (Wrapper a) where
show (Wrapper edit) = show edit
main :: IO ()
main = print $ Wrapper $ Just $ Type 3
-- output: Type
That said, I find this behavior confusing and would steer clear of it in production code.
As #dfeuer notes in a comment and linked code, the overlapping instance is problematic. For example, if we add this innocent function to the code of this answer:
foo :: Show a => Maybe a -> String
foo = show
The module ceases to compile:
* Overlapping instances for Show (Maybe a)
arising from a use of `show'
Matching instances:
instance Show a => Show (Maybe a) -- Defined in `GHC.Show'
instance [overlap ok] Show (Maybe Type) -- Defined at Main.hs:14:27
(The choice depends on the instantiation of `a'
But now I'm confused. Why doesn't the exact same type error happen with the instance definition Show (Wrapper a) in the original question?
The reason foo fails to compile seems to be the last bullet point in the description of the instance search procedure:
Now find all instances, or in-scope given constraints, that unify with
the target constraint, but do not match it. [here, Show (Maybe Type)] Such non-candidate
instances might match when the target constraint is further
instantiated. If all of them are incoherent top-level instances, the
search succeeds, returning the prime candidate. Otherwise the search
fails.
[...]
The final bullet (about unifiying instances) makes GHC
conservative about committing to an overlapping instance. For example:
f :: [b] -> [b]
Suppose that from the RHS of f we get the
constraint C b [b]. But GHC does not commit to instance (C), because
in a particular call of f, b might be instantiated to Int, in which
case instance (D) would be more specific still. So GHC rejects the
program.
Perhaps—unlike normal functions—instance definitions are exempt from this particular rule, but I don't see that mentioned in the docs.

Function that behaves differently depending on which type classes the argument belong to

In Haskell, is there any way to declare function it behaves differently depending on whether the type of a argument is an instance of specific type class?
For example, can I define genericShow in the following example?
-- If type `a` is an instance of `Show`.
genericShow :: Show a => a -> String
genericShow = show
-- If type `a` is not an instance of `Show`.
genericShow :: a -> String
genericShow _ = "(Cannot be shown)"
> genericShow 3
"3"
> genericShow const
"(Cannot be shown)"
No.
The closest you can get is to use Overlapping instances, with a catch-all instance for anything not having a more specific Show instance.
instance {-# OVERLAPPABLE #-} Show a where
show _ = "(Cannot be shown)"
Overlapping instances come with lots of caveats: see topics like 'orphan instances', 'Incoherent instances'. That's particularly awkward with Prelude classes like Show, because there's likely to be lots of instances hidden away in libraries.
As #duplode says, there are many dangers. Almost certainly there's a better way to achieve whatever it is you think you want.

GHC doesn't pick the only available instance

I'm trying to write a CSS DSL in Haskell, and keep the syntax as close to CSS as possible. One difficulty is that certain terms can appear both as a property and value. For example flex: you can have "display: flex" and "flex: 1" in CSS.
I've let myself inspire by the Lucid API, which overrides functions based on the function arguments to generate either attributes or DOM nodes (which sometimes also share names, eg <style> and <div style="...">).
Anyway, I've ran into a problem that GHC fails to typecheck the code (Ambiguous type variable), in a place where it is supposed to pick one of the two available typeclass instances. There is only one instance which fits (and indeed, in the type error GHC prints "These potential instance exist:" and then it lists just one). I'm confused that given the choice of a single instance, GHC refuses to use it. Of course, if I add explicit type annotations then the code compiles. Full example below (only dependency is mtl, for Writer).
{-# LANGUAGE FlexibleInstances #-}
module Style where
import Control.Monad.Writer.Lazy
type StyleM = Writer [(String, String)]
newtype Style = Style { runStyle :: StyleM () }
class Term a where
term :: String -> a
instance Term String where
term = id
instance Term (String -> StyleM ()) where
term property value = tell [(property, value)]
display :: String -> StyleM ()
display = term "display"
flex :: Term a => a
flex = term "flex"
someStyle :: Style
someStyle = Style $ do
flex "1" -- [1] :: StyleM ()
display flex -- [2]
And the error:
Style.hs:29:5: error:
• Ambiguous type variable ‘a0’ arising from a use of ‘flex’
prevents the constraint ‘(Term
([Char]
-> WriterT
[(String, String)]
Data.Functor.Identity.Identity
a0))’ from being solved.
(maybe you haven't applied a function to enough arguments?)
Probable fix: use a type annotation to specify what ‘a0’ should be.
These potential instance exist:
one instance involving out-of-scope types
instance Term (String -> StyleM ()) -- Defined at Style.hs:17:10
• In a stmt of a 'do' block: flex "1"
In the second argument of ‘($)’, namely
‘do { flex "1";
display flex }’
In the expression:
Style
$ do { flex "1";
display flex }
Failed, modules loaded: none.
I've found two ways how to make this code compile, none of which I'm happy with.
Add explicit annotation where the flex function is used ([1]).
Move the line where flex is used to the end of the do block (eg. comment out [2]).
One difference between my API and Lucid is that the Lucid terms always take one argument, and Lucid uses fundeps, which presumably gives the GHC typechecker more information to work with (to choose the correct typeclass instance). But in my case the terms don't always have an argument (when they appear as the value).
The problem is that the Term instance for String -> StyleM () only exists when StyleM is parameterized with (). But in a do-block like
someStyle :: Style
someStyle = Style $ do
flex "1"
return ()
there is not enough information to know which is the type parameter in flex "1", because the return value is thrown away.
A common solution to this problem is the "constraint trick". It requires type equality constraints, so you have to enable {-# LANGUAGE TypeFamilies #-}
or {-# LANGUAGE GADTs #-} and tweak the instance like this:
{-# LANGUAGE TypeFamilies #-}
instance (a ~ ()) => Term (String -> StyleM a) where
term property value = tell [(property, value)]
This tells the compiler: "You don't need to know the precise type a to get the instance, there is one for all types! However, once the instance is determined, you'll always find that the type was () after all!"
This trick is the typeclass version of Henry Ford's "You can have any color you like, as long as it's black." The compiler can find an instance despite the ambiguity, and finding the instance gives him enough information to resolve the ambiguity.
It works because Haskell's instance resolution never backtracks, so once an instance "matches", the compiler has to commit to any equalities it discovers in the preconditions of the instance declaration, or throw a type error.
There is only one instance which fits (and indeed, in the type error GHC prints "These potential instance exist:" and then it lists just one). I'm confused that given the choice of a single instance, GHC refuses to use it.
Type classes are open; any module could define new instances. So GHC never assumes that it knows about all instances, when checking a use of a type class. (With the possible exception of the bad extensions like OverlappingInstances.) Logically, then, the only possible answers to a question "is there an instance for C T" are "yes" and "I don't know". To answer "no" risks incoherence with another part of your program that does define an instance C T.
So, you should not imagine the compiler iterating over every declared instance and seeing whether it fits at the particular use site of interest, because what would it do with all the "I don't know"s? Instead, the process works like this: infer the most general type that could be used at the particular use site and query the instance store for the needed instance. The query can return a more general instance than the one needed, but it can never return a more specific instance, since it would have to choose which more specific instance to return; then your program is ambiguous.
One way to think about the difference is that iterating over all declared instances for C would take linear time in the number of instances, while querying the instance store for a specific instance only has to examine a constant number of potential instances. For example, if I want to type check
Left True == Left False
I need an instance for Eq (Either Bool t), which can only be satisfied by one of
instance Eq (Either Bool t)
instance Eq (Either a t) -- *
instance Eq (f Bool t)
instance Eq (f a t)
instance Eq (g t)
instance Eq b
(The instance marked * is the one that actually exists, and in standard Haskell (without FlexibleInstances) it's the only one of these instances that is legal to declare; the traditional restriction to instances of the form C (T var1 ... varN) makes this step easy since there will always be exactly one potential instance.)
If instances are stored in something like a hash table then this query can be done in constant time regardless of the number of declared instances of Eq (which is probably a pretty large number).
In this step, only instance heads (the stuff to the right of the =>) are examined. Along with a "yes" answer, the instance store can return new constraints on type variables that come from the context of the instance (the stuff to the left of the =>). These constraints then need to be solved in the same manner. (This is why instances are considered to overlap if they have overlapping heads, even if their contexts look mutually exclusive, and why instance Foo a => Bar a is almost never a good idea.)
In your case, since a value of any type can be discarded in do notation, we need an instance for Term (String -> StyleM a). The instance Term (String -> StyleM ()) is more specific, so it's useless in this case. You could either write
do
() <- flex "1"
...
to make the needed instance more specific, or make the provided instance more general by using the type equality trick as explained in danidiaz's answer.

Why do I have to use newtype when my data type declaration only has one constructor? [duplicate]

This question already has answers here:
Difference between `data` and `newtype` in Haskell
(2 answers)
Closed 8 years ago.
It seems that a newtype definition is just a data definition that obeys some restrictions (e.g., only one constructor), and that due to these restrictions the runtime system can handle newtypes more efficiently. And the handling of pattern matching for undefined values is slightly different.
But suppose Haskell would only knew data definitions, no newtypes: couldn't the compiler find out for itself whether a given data definition obeys these restrictions, and automatically treat it more efficiently?
I'm sure I'm missing out on something, there must be some deeper reason for this.
Both newtype and the single-constructor data introduce a single value constructor, but the value constructor introduced by newtype is strict and the value constructor introduced by data is lazy. So if you have
data D = D Int
newtype N = N Int
Then N undefined is equivalent to undefined and causes an error when evaluated. But D undefined is not equivalent to undefined, and it can be evaluated as long as you don't try to peek inside.
Couldn't the compiler handle this for itself.
No, not really—this is a case where as the programmer you get to decide whether the constructor is strict or lazy. To understand when and how to make constructors strict or lazy, you have to have a much better understanding of lazy evaluation than I do. I stick to the idea in the Report, namely that newtype is there for you to rename an existing type, like having several different incompatible kinds of measurements:
newtype Feet = Feet Double
newtype Cm = Cm Double
both behave exactly like Double at run time, but the compiler promises not to let you confuse them.
According to Learn You a Haskell:
Instead of the data keyword, the newtype keyword is used. Now why is
that? Well for one, newtype is faster. If you use the data keyword to
wrap a type, there's some overhead to all that wrapping and unwrapping
when your program is running. But if you use newtype, Haskell knows
that you're just using it to wrap an existing type into a new type
(hence the name), because you want it to be the same internally but
have a different type. With that in mind, Haskell can get rid of the
wrapping and unwrapping once it resolves which value is of what type.
So why not just use newtype all the time instead of data then? Well,
when you make a new type from an existing type by using the newtype
keyword, you can only have one value constructor and that value
constructor can only have one field. But with data, you can make data
types that have several value constructors and each constructor can
have zero or more fields:
data Profession = Fighter | Archer | Accountant
data Race = Human | Elf | Orc | Goblin
data PlayerCharacter = PlayerCharacter Race Profession
When using newtype, you're restricted to just one constructor with one
field.
Now consider the following type:
data CoolBool = CoolBool { getCoolBool :: Bool }
It's your run-of-the-mill algebraic data type that was defined with
the data keyword. It has one value constructor, which has one field
whose type is Bool. Let's make a function that pattern matches on a
CoolBool and returns the value "hello" regardless of whether the Bool
inside the CoolBool was True or False:
helloMe :: CoolBool -> String
helloMe (CoolBool _) = "hello"
Instead of applying this function to a normal CoolBool, let's throw it a curveball and apply it to undefined!
ghci> helloMe undefined
"*** Exception: Prelude.undefined
Yikes! An exception! Now why did this exception happen? Types defined
with the data keyword can have multiple value constructors (even
though CoolBool only has one). So in order to see if the value given
to our function conforms to the (CoolBool _) pattern, Haskell has to
evaluate the value just enough to see which value constructor was used
when we made the value. And when we try to evaluate an undefined
value, even a little, an exception is thrown.
Instead of using the data keyword for CoolBool, let's try using
newtype:
newtype CoolBool = CoolBool { getCoolBool :: Bool }
We don't have to
change our helloMe function, because the pattern matching syntax is
the same if you use newtype or data to define your type. Let's do the
same thing here and apply helloMe to an undefined value:
ghci> helloMe undefined
"hello"
It worked! Hmmm, why is that? Well, like we've said, when we use
newtype, Haskell can internally represent the values of the new type
in the same way as the original values. It doesn't have to add another
box around them, it just has to be aware of the values being of
different types. And because Haskell knows that types made with the
newtype keyword can only have one constructor, it doesn't have to
evaluate the value passed to the function to make sure that it
conforms to the (CoolBool _) pattern because newtype types can only
have one possible value constructor and one field!
This difference in behavior may seem trivial, but it's actually pretty
important because it helps us realize that even though types defined
with data and newtype behave similarly from the programmer's point of
view because they both have value constructors and fields, they are
actually two different mechanisms. Whereas data can be used to make
your own types from scratch, newtype is for making a completely new
type out of an existing type. Pattern matching on newtype values isn't
like taking something out of a box (like it is with data), it's more
about making a direct conversion from one type to another.
Here's another source. According to this Newtype article:
A newtype declaration creates a new type in much the same way as data.
The syntax and usage of newtypes is virtually identical to that of
data declarations - in fact, you can replace the newtype keyword with
data and it'll still compile, indeed there's even a good chance your
program will still work. The converse is not true, however - data can
only be replaced with newtype if the type has exactly one constructor
with exactly one field inside it.
Some Examples:
newtype Fd = Fd CInt
-- data Fd = Fd CInt would also be valid
-- newtypes can have deriving clauses just like normal types
newtype Identity a = Identity a
deriving (Eq, Ord, Read, Show)
-- record syntax is still allowed, but only for one field
newtype State s a = State { runState :: s -> (s, a) }
-- this is *not* allowed:
-- newtype Pair a b = Pair { pairFst :: a, pairSnd :: b }
-- but this is:
data Pair a b = Pair { pairFst :: a, pairSnd :: b }
-- and so is this:
newtype Pair' a b = Pair' (a, b)
Sounds pretty limited! So why does anyone use newtype?
The short version The restriction to one constructor with one field
means that the new type and the type of the field are in direct
correspondence:
State :: (s -> (a, s)) -> State s a
runState :: State s a -> (s -> (a, s))
or in mathematical terms they are isomorphic. This means that after
the type is checked at compile time, at run time the two types can be
treated essentially the same, without the overhead or indirection
normally associated with a data constructor. So if you want to declare
different type class instances for a particular type, or want to make
a type abstract, you can wrap it in a newtype and it'll be considered
distinct to the type-checker, but identical at runtime. You can then
use all sorts of deep trickery like phantom or recursive types without
worrying about GHC shuffling buckets of bytes for no reason.
See the article for the messy bits...
Simple version for folks obsessed with bullet lists (failed to find one, so have to write it by myself):
data - creates new algebraic type with value constructors
Can have several value constructors
Value constructors are lazy
Values can have several fields
Affects both compilation and runtime, have runtime overhead
Created type is a distinct new type
Can have its own type class instances
When pattern matching against value constructors, WILL be evaluated at least to weak head normal form (WHNF) *
Used to create new data type (example: Address { zip :: String, street :: String } )
newtype - creates new “decorating” type with value constructor
Can have only one value constructor
Value constructor is strict
Value can have only one field
Affects only compilation, no runtime overhead
Created type is a distinct new type
Can have its own type class instances
When pattern matching against value constructor, CAN be not evaluated at all *
Used to create higher level concept based on existing type with distinct set of supported operations or that is not interchangeable with original type (example: Meter, Cm, Feet is Double)
type - creates an alternative name (synonym) for a type (like typedef in C)
No value constructors
No fields
Affects only compilation, no runtime overhead
No new type is created (only a new name for existing type)
Can NOT have its own type class instances
When pattern matching against data constructor, behaves the same as original type
Used to create higher level concept based on existing type with the same set of supported operations (example: String is [Char])
[*] On pattern matching laziness:
data DataBox a = DataBox Int
newtype NewtypeBox a = NewtypeBox Int
dataMatcher :: DataBox -> String
dataMatcher (DataBox _) = "data"
newtypeMatcher :: NewtypeBox -> String
newtypeMatcher (NewtypeBox _) = "newtype"
ghci> dataMatcher undefined
"*** Exception: Prelude.undefined
ghci> newtypeMatcher undefined
“newtype"
Off the top of my head; data declarations use lazy evaluation in access and storage of their "members", whereas newtype does not. Newtype also strips away all previous type instances from its components, effectively hiding its implementation; whereas data leaves the implementation open.
I tend to use newtype's when avoiding boilerplate code in complex data types where I don't necessarily need access to the internals when using them. This speeds up both compilation and execution, and reduces code complexity where the new type is used.
When first reading about this I found this chapter of a Gentle Introduction to Haskell rather intuitive.

Resources