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

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.

Related

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.

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

How to declare instances of a typeclass (like Show) for all types in my own typeclass?

I have a typeclass:
class Wrapper w where
open :: w -> Map String Int
close :: Map String Int -> w
It doesn't look very useful, but I use it to strongly (not just a type synonym) distinguish between semantically different varieties of Map String Ints:
newtype FlapMap = Flap (Map String Int)
newtype SnapMap = Snap (Map String Int)
...
and still have functions that operate on any type of the class.
Is there a better way to do this distinction (maybe without the Wrapper instances boilerplate)?
I want to do this:
instance (Wrapper wrapper) => Show wrapper where
show w = show $ toList $ open w
instead of writing many boilerplate Show instances as well.
Via FlexibleInstances and UndecidableInstances, GHC leads me to a point where it thinks my instance declaration applies to everything, as it allegedly clashes with the other Show instances in my code and in GHC.Show. HaskellWiki and StackOverflow answerers and HaskellWiki convince me OverlappingInstances is not quite safe and possibly confusing. GHC doesn't even suggest it.
Why does GHC first complain about not knowing which instance of fx Show Int to pick (so why it doesn't look at the constraint I give at compile time?) and then, being told that instances may overlap, suddenly know what to do?
Can I avoid allowing OverlappingInstances with my newtypes?
You can’t do this without OverlappingInstances, which as you mention, is unpredictable. It won’t help you here, anyway, so you pretty much can’t do this at all without a wrapper type.
That’s rather unsatisfying, of course, so why is this the case? As you’ve already determined, GHC does not look at the instance context when picking an instance, only the instance head. Why? Well, consider the following code:
class Foo a where
fooToString :: a -> String
class Bar a where
barToString :: a -> String
data Something = Something
instance Foo Something where
fooToString _ = "foo something"
instance Bar Something where
barToString _ = "bar something"
instance Foo a => Show a where
show = fooToString
instance Bar a => Show a where
show = barToString
If you consider the Foo or Bar typeclasses in isolation, the above definitions make sense. Anything that implements the Foo typeclass should get a Show instance “for free”. Unfortunately, the same is true of the Bar instance, so now you have two valid instances for show Something.
Since typeclasses are always open (and indeed, Show must be open if you are able to define your own instances for it), it’s impossible to know that someone will not come along and add their own similar instance, then create an instance on your datatype, creating ambiguity. This is effectively the classic diamond problem from OO multiple inheritance in typeclass form.
The best you can get is to create a wrapper type that provides the relevant instances:
{-# LANGUAGE ExistentialQuantification #-}
data ShowableWrapper = forall w. Wrapper w => ShowableWrapper w
instance Show ShowableWrapper where
show (ShowableWrapper w) = show . toList $ open w
At that point, though, you really aren’t getting much of an advantage over just writing your own showWrapper :: Wrapper w => w -> String function.

What should be my expectations for Haskell's "deriving"?

Apologies in advance for a beginner question, but I have struggled to find useful info on this. I was working through "Learn You Haskell for Great Good" and am trying to understand the deriving keyword, which seems like Java's implements but supposedly with cool automatic code generation because of the category theory stuff or something. I declare a data structure for 2-vectors like
data R2 = R2 {x :: Double, y :: Double} deriving (Show)
Then I can use it for things like
show (R2 1.0 2.0)
Now what I'd like to do is vector addition and scalar multiplication, like
(2.0 * (R2 1.0 2.0)) + (R2 3.0 4.0)
but when I try
Prelude> data R2 = R2 { x :: Double, y :: Double} deriving (Num,Show)
<interactive>:3:52:
Can't make a derived instance of `Num R2':
`Num' is not a derivable class
In the data declaration for `R2'
So the compiler figured out how to show the cartesian product of primitive types, but addition is too hard? Maybe Num isn't the right type class to derive? How often can one expect to derive a type class and get working code without additional work, like how I didn't have to write my own show function?
Thanks very much,
John
trying to understand the deriving keyword, which seems like Java's implements but supposedly with cool automatic code generation
instance is a bit more like implements, in that you state that a type is an instance of a type class and then write the implementations. deriving is all about the cool automatic generation of those implementations (though it does subsume instance).
How often can one expect to derive a type class and get working code without additional work, like how I didn't have to write my own show function?
Alexey Romanov's answer covers for which classes deriving works. There is also another way to auto-generate instances: using generics. From a bird's eye view, it works like this: you describe what an instance should look like for a generic type and then, for any type you want to have an instance, derive Generic and add an empty (i.e. with no implementations, as they will be generated automatically) instance declaration. Some libraries like aeson and binary offer generic instances ready to use, and you can of course roll your own for your classes.
See https://downloads.haskell.org/~ghc/7.10.2/docs/html/users_guide/deriving.html:
In Haskell 98, the only classes that may appear in the deriving clause are the standard classes Eq, Ord, Enum, Ix, Bounded, Read, and Show.
GHC also allows deriving Generic, Functor, Data, Typeable, Foldable and Traversable for data declarations, and any classes for newtype declarations (after enabling the relevant extensions, as listed in the linked page).
Here's one reason that you can't derive the Num class
data Vector = Vector Int Int
instance Num Vector where
Vector a b + Vector c d = Vector (a + c) (b + d)
Vector a b * Vector c d = Vector (a * c) (b * d)
data Complex = Complex Int Int
instance Num Complex where
Complex a b + Complex c d = Complex (a + c) (b + d)
Complex a b * Complex c d = Complex (a * c - b * d) (a * d + b * c)
Both are sensible instances that a real programmer might want to define. For a given data definition with two Int fields, which instance should the deriving clause pick?
The Haskell Report 2010 (the document that describes the Haskell language and which all implementions should follow) defines the conditions for deriving a class C as follows:
C is one of Eq, Ord, Enum, Bounded, Show, or Read.
There is a context cx′ such that cx′ ⇒ C tij holds for each of the constituent types tij.
If C is Bounded, the type must be either an enumeration (all constructors must be nullary) or have only one constructor.
If C is Enum, the type must be an enumeration.
There must be no explicit instance declaration elsewhere in the program that makes T u1 … uk an instance of C.
If the data declaration has no constructors (i.e. when n = 0), then no classes are derivable.
Also, later in the report, it is said that it's also possible to derive Data.Ix instances.
To find out how a particular instance is derived exactly (for example, what does the derived Show instance output?), read the section about it in the report. That section only gives implementations for the cases where the above conditions are met. That's why it's impossible to derive Num instances: it's not specified what that instance should do!
GHC also provides a few extensions that make allow for deriving more classes.
Those extensions are not part of standard Haskell, so they have to enabled explicitly. For example, if GenericNewtypeDeriving is enabled, you can write the following:
newtype MyInt = MyInt Int deriving (Num)
-- By GenericNewtypeDeriving, GHC will just "copy" the instance
-- for the base type of the newtype, in this case, it'll use the `Num Int` instance.
You can read about these extensions in the GHC user guide
Sadly, deriving only works for a small handful of classes, where the necessary code is hard-wired into the compiler. You can write instances yourself for any class, but only this small handful can be derived automatically.

Derive Eq and Show for type alias in Haskell

I've the following type alias
data Bindable = Const Value
| Variable Location
| Func Function
| Proc
deriving (Eq, Show)
type Function = Argument -> Store -> Value
but the compiler gives me an error
No instance for (Show Function)
arising from the 'deriving' clause of a data type declaration
Possible fix:
add an instance declaration for (Show Function)
or use a standalone 'deriving instance' declaration,
so you can specify the instance context yourself
When deriving the instance for (Show Bindable)
Can I define Show & Eq for Function? If not then what would be the solution? Should I define Eq and Show to Argument, Store and Value?
Type class instances may only be defined for "real" types, as defined by a data or newtype declaration. A type declaration is a "fake" type—just an abbreviation for a longer type.
But that's just problem #1 in this case. Problem #2 is that even if you do this...
newtype Function = Function (Argument -> Store -> Value)
...there might still be no truly useful Show instance for Function. How do turn a function into a string? There are two strategies. First, the "just give up" strategy:
instance Show Function where
show _ = "<some Function, no clue what it does>"
Second, the "canonical example" strategy, where you apply the Function to some canonical Argument and Store and show these together with the Value result:
instance Show Function where
show (Function fn) = "Function: "
++ show defaultArgument
++ " -> "
++ show defaultStore
++ " -> "
++ show (fn defaultArgument defaultStore)
The idea here is to display the Function as one particular argument/value mapping of it that might help you identify it more precisely than just using the same constant string for all of them. Whether this helps or not depends on what your functions do.
But now we have problem #3: neither of these obeys the intent/contract of the Show and Read classes, which is that read (show x) is equivalent to x. (People do often ignore this intent, however, just because they want to print something and Show is the quickest ticket. So much that, as Thomas DuBuisson points out, there's a standard module Text.Show.Functions that implements the "just give up" strategy.)
As for the Eq class, the answer is that it's just impossible in general to compare two functions for equality. (If I recall correctly, it's equivalent to solving the Halting Problem, but don't quote me on that.) If your solution requires you to compare functions for equality, you need a new solution...
Just import Text.Show.Functions. Your type is just an alias, the error message is saying it can't find an instance of Show for (->), but an instance is available in that module.
Prelude> import Text.Show.Functions
Prelude Text.Show.Functions> show (+1)
"<function>"

Resources