I know of the documentation for -XUndecidableInstances, but I thought I'd ask for an elaboration.
Suppose I have two multi-parameter typeclasses (allowed with -XMultiParamTypeClasses)
class Foo a b
class Goo a b
Now, suppose I have a parameterized data type
data Bar a b
which I want to make an instance of Foo when one of its parameters is part of an instance of Goo. I'm not sure the previous sentence uses exact terminology, so here's what I want to write:
instance (Goo c d) => Foo d (Bar a d)
I'm not allowed to without the UndecidableInstances extension. Am I correct in thinking this is because the instance doesn't refer to the c type?
Should I...
Just enable the extension? Can somebody elaborate on what kinds of trouble it can get me into?
Add another parameter to Foo, so that the last instance declaration becomes something like Foo c d (Bar a d)? A problem with this is that I might have other instances of Foo that never make any reference to any such "fourth type parameter" (i.e. there are instances of the form instance Foo A B in unrelated parts of my code), so these would break. I'd rather fix my instance, not my class.
Create a new class FooGoo with enough parameters? I would feel like I'm repeating myself in that case, but at least I wouldn't break unrelated classes.
Does anyone have any words of wisdom?
Am I correct in thinking this is because the instance doesn't refer to the c type?
Yes, your code does not adhere to (from here):
For each assertion in the context: No
type variable has more occurrences in
the assertion than in the head
In general, you should be safe unless you add other instances that would, together, form a loop. Things only get really hairy (and compiler-dependent) when it comes to OverlappingInstances, and rightout evil when you go IncoherentInstances.
Without knowing more about what you're trying to accomplish it's hard to give sound design advice, but the first thing to check is whether you really, really need to have c as a parameter to Goo. You might be able to do express what you want to accomplish like this:
class Goo d where
bar :: d c -> Int
baz :: Quux c => d c -> Int
Related
I have the following type family in haskell :
type family Foo (a :: Bar) :: * where
followed by a bunch of equality. I want to put a constraint on the kind return to ensure they're all instance of a typeclass. How can i do that ?
Seems like you're looking for
class (YourConstraint (Foo a)) => Fooish (a :: Bar) where
type Foo a :: Type
As Carl noted, this is somewhat analogous to the old data declaration style with
data C a => D a = D ...
which is widely considered a bad idea because it's not possible to use the constraint, all it accomplishes is preventing to build values that don't obey the constraint.
But unlike those data declarations, a constraint to an associated type family is useful IMO, because there's an easy way to get at the constrait whenever it's needed: you just need to mention Fooish.
In Haskell, it's better not to do that. (See also the desire to put constraints on type variables in data declarations.) You should put constraints where they're actually going to be used. That will still get called out during type checking if it's missing when it's needed, but it will allow things that don't need it to be more flexible.
First of all, I want to clarify that I've tried to find a solution to my problem googling but I didn't succeed.
I need a way to compare two expressions. The problem is that these expressions are not comparable. I'm coming from Erlang, where I can do :
case exp1 of
exp2 -> ...
where exp1 and exp2 are bound. But Haskell doesn't allow me to do this. However, in Haskell I could compare using ==. Unfortunately, their type is not member of the class Eq. Of course, both expressions are unknown until runtime, so I can't write a static pattern in the source code.
How could compare this two expressions without having to define my own comparison function? I suppose that pattern matching could be used here in some way (as in Erlang), but I don't know how.
Edit
I think that explaining my goal could help to understand the problem.
I'm modyfing an Abstract Syntax Tree (AST). I am going to apply a set of rules that are going to modify this AST, but I want to store the modifications in a list. The elements of this list should be a tuple with the original piece of the AST and its modification. So the last step is to for each tuple search for a piece of the AST that is exactly the same, and substitute it by the second element of the tuple. So, I will need something like this:
change (old,new):t piece_of_ast =
case piece_of_ast of
old -> new
_ -> piece_of_ast
I hope this explanation clarify my problem.
Thanks in advance
It's probably an oversight in the library (but maybe I'm missing a subtle reason why Eq is a bad idea!) and I would contact the maintainer to get the needed Eq instances added in.
But for the record and the meantime, here's what you can do if the type you want to compare for equality doesn't have an instance for Eq, but does have one for Data - as is the case in your question.
The Data.Generics.Twins package offers a generic version of equality, with type
geq :: Data a => a -> a -> Bool
As the documentation states, this is 'Generic equality: an alternative to "deriving Eq" '. It works by comparing the toplevel constructors and if they are the same continues on to the subterms.
Since the Data class inherits from Typeable, you could even write a function like
veryGenericEq :: (Data a, Data b) => a -> b -> Bool
veryGenericEq a b = case (cast a) of
Nothing -> False
Maybe a' -> geq a' b
but I'm not sure this is a good idea - it certainly is unhaskelly, smashing all types into one big happy universe :-)
If you don't have a Data instance either, but the data type is simple enough that comparing for equality is 100% straightforward then StandaloneDeriving is the way to go, as #ChristianConkle indicates. To do this you need to add a {-# LANGUAGE StandaloneDeriving #-} pragma at the top of your file and add a number of clauses
deriving instance Eq a => Eq (CStatement a)
one for each type CStatement uses that doesn't have an Eq instance, like CAttribute. GHC will complain about each one you need, so you don't have to trawl through the source.
This will create a bunch of so-called 'orphan instances.' Normally, an instance like instance C T where will be defined in either the module that defines C or the module that defines T. Your instances are 'orphans' because they're separated from their 'parents.' Orphan instances can be bad because you might start using a new library which also has those instances defined; which instance should the compiler use? There's a little note on the Haskell wiki about this issue. If you're not publishing a library for others to use, it's fine; it's your problem and you can deal with it. It's also fine for testing; if you can implement Eq, then the library maintainer can probably include deriving Eq in the library itself, solving your problem.
I'm not familiar with Erlang, but Haskell does not assume that all expressions can be compared for equality. Consider, for instance, undefined == undefined or undefined == let x = x in x.
Equality testing with (==) is an operation on values. Values of some types are simply not comparable. Consider, for instance, two values of type IO String: return "s" and getLine. Are they equal? What if you run the program and type "s"?
On the other hand, consider this:
f :: IO Bool
f = do
x <- return "s" -- note that using return like this is pointless
y <- getLine
return (x == y) -- both x and y have type String.
It's not clear what you're looking for. Pattern matching may be the answer, but if you're using a library type that's not an instance of Eq, the likely answer is that comparing two values is actually impossible (or that the library author has for some reason decided to impose that restriction).
What types, specifically, are you trying to compare?
Edit: As a commenter mentioned, you can also compare using Data. I don't know if that is easier for you in this situation, but to me it is unidiomatic; a hack.
You also asked why Haskell can't do "this sort of thing" automatically. There are a few reasons. In part it's historical; in part it's that, with deriving, Eq satisfies most needs.
But there's also an important principle in play: the public interface of a type ideally represents what you can actually do with values of that type. Your specific type is a bad example, because it exposes all its constructors, and it really looks like there should be an Eq instance for it. But there are many other libraries that do not expose the implementation of their types, and instead require you to use provided functions (and class instances). Haskell allows that abstraction; a library author can rely on the fact that a consumer can't muck about with implementation details (at least without using unsafe tools like unsafeCoerce).
I am trying to understand type classes in Haskell.
I pose the question using a simple example:
Lets consider two datatypes, A and B.
Lets also assume that a1 and a2 are of type A and b1 and b2 are of type B.
Now let's assume that we want to define functions to check if a1 equals a2 and whether b1 is the same as b2.
For this we have two options:
Option 1:
Define two equality functions using separate names like this :
eqA :: A -> A -> Bool
eqA = ...
eqB :: B -> B -> Bool
eqB = ...
Now if we want to check if a1 equals a2 then we write : eqA a1 a2, similarly for B : eqB b1 b2.
Option 2:
We make A and B instances of the Eq typeclass.
In this case we can use the == sign for checking for equality as follows.
a1==a2
b1==b2
So, now the question : as far as I understand the sole purpose of the existence of type classes is that we can reuse the function name == for the equivalence checking function, as shown in Option 2. So if we use type classes we do not have to use different function names for essentially the same purpose ( i.e. checking for equality).
Is that correct? Is name reuse the only advantage that type classes give? Or is there something more to type classes ?
In other words, given any program using type classes, I could rewrite that program to an isomorphic program that does not use type classes by giving separate names (i.e. eqA and eqB) to the overloaded function names (i.e. == in Option 2) that are defined in the type class instance declarations.
In the simple example this transformation would replace Option 2 with Option 1.
Is such a mechanic transformation always possible?
Is that not what the compiler is doing behind the scenes?
Thank you for reading.
EDIT:
Thanks for all the illuminating answers !
There is this very good article regarding type class which shows their desugaring process: https://www.fpcomplete.com/user/jfischoff/instances-and-dictionaries
So, yes, you could do without them, but you will need to have a different function for each type as you did in your question, or you will need to pass the instance dictionary explicitly as described in the article, while the type class do it implicitly so you don't need to bother. In many cases, you would end up with a LOT of functions with different names!
Nevertheless, your question leads also to the fact that type classes are often too much used when other patterns would solve the problem as well:
http://lukepalmer.wordpress.com/2010/01/24/haskell-antipattern-existential-typeclass/
Type classes are syntax sugar, so there is nothing that you cannot do without them. It is just a question of how hard it would be to do without them.
My favorite example is QuickCheck, which uses type classes to recurse over function arguments. (Yes, you can do that.) QuickCheck takes a function with an arbitrary number of arguments, and auto-generates random test data for each argument, and checks that the function always returns true. It uses type classes to figure out how to "randomly" generate data of each individual type. And it uses clever type class tricks to support functions with any number of arguments.
You don't need this; you could have a test1 function, and then a test2 function, and then a test3 function, etc. But it's nice to be able to have just "one function" which automatically figures out how many arguments there are. Indeed, without type classes you'd end up having to write something like
test_Int
test_Double
test_Char
test_Int_Int
test_Int_Double
test_Int_Char
test_Double_Int
test_Double_Double
test_Double_Char
...
...for every possible combination of inputs. And that would just be really annoying. (And good luck trying to extend it within your own code.)
Really, type classes make your code more high-level and declarative. It makes it easier to see what the code is trying to do. (Most of the time.) There are really advanced cases where I start to think maybe the design isn't quite right, but for the vast majority of stuff, type classes work really well.
For the most part the answer is that type classes give you name re-use. Sometimes the amount of name re-use you get is more than you might think.
A Type Class is somewhat similar to an Interface in Object Oriented languages. Occasionally someone might ask "is the only purpose of an Interface to enforce contracts in APIs?". We might see this code in java
public <A> void foo (List<A> list) {
list.clear();
}
List<A> list = new ArrayList<>();
List<A> list2 = new LinkedList<>();
foo(list);
foo(list2);
Both ArrayList and LinkedList implement the List interface. As such, we can write a general function that foo which operates on any List. This is similar to your Eq example. In Haskell we have many higher order functions like this. For example foldl can be implemented by more than just lists, and we can use foldl on anything that uses Foldable from Data.Foldable.
In OO you can use generics to do some really interesting abstractions and inheritance (e.g. in Java things like Foo<A extends Foo<A>>). In Haskell we can use Type Classes to do different types of abstractions.
Let's take the Monad class, which requires you to implement "return". Maybe implements return something like this:
instance Monad Maybe where
return a = Just a
Whilst List implements return like this:
instance Monad [] where
return a = [a]
Return, as it is done in Haskell, is not possible in a language like Java. In Java if you want to create a new instance of something in a container (say a new List<String>) you have to use new ArrayList<String>();. You can't create an instance of something because it fulfills a contract. While in Haskell we can write this code which would not be possible in Java:
foobar :: (Monad m) => (m a -> m b) -> a -> m b
foobar g a = g $ return a
Now I can pass anything to foobar. I could pass a function Maybe a -> Maybe b or [a] -> [b] and foobar will still accept.
Now of course this could all be broken down and functions could be written one by one. Just like Java could ignore interfaces and implement everything from scratch on each class of List. But just like the inheritance that's possible in OO once you factor in generics, in Haskell we can do some interesting things in Type Classes using language extensions. For example, check out http://www.haskell.org/haskellwiki/Functional_dependencies_vs._type_families
I am an Haskell beginner writing a toy compiler in Haskell for some simple language, and, after having done the parser, I started working on the first "stages" (type checking, some simplifications, code generation etc). My AST datatype looks something like this:
data Ast a = ConstInt Int a | Variable String a | SomeComplexThing .... a
The point being, I wish to use that a slot for storing information after each pass: say, after the parsing we have a Ast Position, then after type checking we have a Ast (Position,TypeInfo) and so on and so forth.
However, I wish to access the values in this payload independently on the stage. As of right now, at different stages, the tuple is of a different type and therefore there is no homogenous automated way to do this. If I am to remove a stage, all is to be changed.
So, the haskell noob in me thought:Typeclasses!
Now, I can easly make a TypeInfoHolder typeclass, and a PositionHolder typeclass, and so on
class TypeInfoHolder a where
getTypeInfo::a->TypeInfo
And have a
data TypeInfoHolderObj a = TypeInfoHolderObj a TypeInfo
and make that an instance of TypeInfoHolder.
Now I want somehow to automatically ensure that each TypeInfoHolderObj a is also an instance of all the classes which a belongs to, that is, for each typeclass A which a implements, then TypeInfoHolderObj a also implements by applying the class's functions to the a member of the TypeInfoHolderObj
I'd just want to know this out of curiosity: it seems the sort of thing that could come up quite often.
You seem to have roughly two questions.
Is it a good idea to use typeclasses to provide the ability to project a certain type out of many others? And,
Is there a way to make types like TypeInfoHolderObj a inherit all of the instances of a
The answer to (1) is a little contested because the "right" use of typeclasses is a little contested. Personally, I think the answer is "yes" and it's backed up a bit in the Lenses literature where typeclasses like HasX are common. This is definitely a stylistic concern, though, so it will be difficult to get a meaningful answer—especially from Stack Overflow.
The answer to (2) is "no" and it's easy to show why. Consider just one of many example instances which would need to be automatically derived
instance Monoid a => Monoid (TypeInfoHolderObj a) where ...
For some types (those which could be newtypes) this instance derivation can be done automatically (see GeneralizedNewtypeDeriving) but for TypeInfoHolderObj it is not possible unless TypeInfo also shares the Monoid instance. If it did, we could do
mempty = TypeInfoHolderObj mempty mempty
mappend (TypeInfoHolderObj a b) (TypeInfoHolderObj c d) =
TypeInfoHolderObj (mappend a c) (mappend b d)
In general, we don't know all of the assumptions required to automatically derive instances like this. It's possible to guess when they might occur, though, as you can expect them to work whenever your instances look a bit like
class Foo a where ...
instance (Foo a, Foo b) => Foo (a, b) where ...
since, effectively, TypeInfoHolderObj a is nothing more than (a, TypeInfo).
In the following code all that I ever do with the return value of foo is use its Show interface
foo :: String
foo = "asdf"
main = do
print foo
Is there a way to modify the type signature offoo to enforce this, forbidding people from treating the string as a list of characters and only letting them access it though the abstract type class interface? I think it might be possible with existential types but I have no idea how.
The reason I want to do this is because in the HDBC database library all the functionality is available as methods of a IConnection type class. I am writing the function that creates the database connection and I want to know if its possible to have its return type reflect the abstract interface instead of returning a concrete Sqlite3 Connection.
Now that I searched a bit I see that there is a ConnWrapper datatype available but I still can't understand how this all fits together. Is returning a ConnWrapper the only way to go?
It's indeed possible with existential types, but it's quite possibly a bad idea.
The way you would do it with an existential type is ConnWrapper, like you said:
data ConnWrapper = forall conn. IConnection conn => ConnWrapper conn
That type is relatively straightforward: It's an IConnection dictionary together with a value of a type compatible with it. If x :: conn, and conn is an instance of IConnection, then ConnWrapper x :: ConnWrapper. Given y :: ConnWrapper, you know nothing about its value's type other than that it's an instance of IConnection. So you can say case y of ConnWrapper z -> disconnect z, but you can't say case y of ConnWrapper z -> z -- there's no Haskell type you can give to that.
(ConnWrapper is also an instance of IConnection directly, and since the class is pretty simple, that means you pretty much never need to pattern-match on ConnWrapper directly. You can just use disconnect y and so on.)
If you were making the API, I'd strongly suggest reconsidering along the lines of the post I linked above, or at least understanding that approach. Many uses of ExistentialTypes in Haskell are actually more complicated than a non-existential approach. For example, you should see why data Foo = forall a. Show a => Foo a is (almost) equivalent to String. It looks like the HDBC may be intended to be used this way, though...