How can I use a type synonym in an instance declaration? - haskell

I'd like to make synonyms for a class constraint like the following (very much simplified) example
{-# LANGUAGE ConstraintKinds #-}
type Foo = Functor
data MyFunctor a = MyFunctor
instance Foo MyFunctor where
fmap _ _ = MyFunctor
but I get fmap is not a (visible) method of class Foo.
It seems like I should be able to do this because the GHC documentation says "... standard constraints, tuples and type synonyms for those two sorts of constraint are permitted in instance contexts and superclasses". I'm on GHC 7.6.

Your case isn't covered by those statements in the GHC documentation. An instance context using Foo is something like:
instance Foo a => Bar a
A superclass would be something like:
class Foo a => Bar a
i.e. you're defining some other class or instance and Foo/Functor is one of the requirements. Here you're actually trying to define Functor itself and you have to use the real class name.

Related

Is there a way to refer directly to typeclass instances in Haskell?

The benefit of this could be to store certain metadata about the type in a canonical location. Sometimes, it isn't convenient to have a value of the type before using some instance methods on it; For instance if I have:
class Foo a where
foo :: String
foo = "Foo"
This is not actually valid Haskell. Instead it seems I have to have something like:
class Foo a where
foo :: a -> String
foo = const "Foo"
and now foo will actually have type Foo a => a -> String, but I would actually like to be able to do something like having a foo with type Instance Foo -> String. For this to be useful in some contexts, it might be also necessary to iterate over all (in-scope?) instances, or in other contexts, to be able to specifically materialize an instance for a given type.
I guess the issue is that instances and typeclasses are not first-class entities in Haskell?
The "old school" way of doing it is providing a "dummy" parameter whose purpose is nothing but helping the compiler find the appropriate instance. In this world, your class would look something like:
data Dummy a = Dummy
class Foo a where
foo :: Dummy a -> String
-- usage:
boolFoo = foo (Dummy :: Dummy Bool)
In fact, this trick was so ubiquitous that the Dummy type was semi-standardized as Data.Proxy.
But in modern GHC there is a better way: TypeApplications.
With this extension enabled, you can just straight up specify the type when calling the class method:
class Foo a where
foo :: String
boolFoo = foo #Bool
(this doesn't only work for class methods; it will work with any generic function, but be careful with the order of type parameters!)
You may also need to enable AllowAmbiguousTypes in order to declare such class. Though I'm not sure I remember this correctly, and I don't have a computer handy to check.
The old way (which I still prefer) is to use a proxy.
import Data.Proxy
class Foo a where
foo :: Proxy a -> String
instance Foo FancyPants where
foo _ = "a fancypants instance"
fooString :: String
fooString = foo (Proxy :: Proxy FancyPants)
So we didn't actually need a value of type FancyPants to use foo, all we needed is a value of Proxy FancyPants -- but you can create proxies of any type you want. This can be done in a polymorphic context too; usually it requires the use of the ScopedTypeVariables extension.
The new way is to use the TypeApplications and AllowAmbiguousTypes extension:
{-# LANGUAGE TypeApplications, AllowAmbiguousTypes #-}
class Foo a where
foo :: String
instance Foo FancyPants where
foo = "a fancypants instance"
fooString :: String
fooString = foo #FancyPants
Which looks nicer, but working with it in practice tends to be more irritating for a reason I can't quite put my finger on.
Did that answer the question?

How to define default implementation in subclass definition in Haskell?

I am new comer of Haskell and following is my question:
given this class:
class MyClass a where
foo :: a -> [a]
then I have a subclass that is more specific:
class (MyClass a) => SubClass a where
foo param = [bar param]
bar :: a -> a
but it doesn't work as expected. I was expecting a default implementation is setup in the definition of SubClass but it doesn't. I will need to define the instance for MyClass seperately, but that sounds stupid. How can I achieve default implementation when I know some subclass satisfies some property definitely?
More specifically, I want to express in Haskell, that when a class satisfies some properties, some functions for its parent can have default implementation. In my example, SubClass has property bar such that I know foo is definitely defined in such a way.
A more general form of this question is, is it a good idea to reuse by using classes and instances?
I found this post: Inclusion of typeclasses with default implementation in Haskell
It's quite close, but still not answering my question totally and their forms are little bit different.
Elaborating on Daniel's answer:
Suppose you have a new datatype MyData, defined as
data MyData = D1 | D2
You want to make MyData an instance of SubClass. You try the obvious solution first.
instance SubClass MyData where
bar x = case x of { D1 -> D2 ; D2 -> D1 }
A quick examination of the type signatures, though, reveals that this won't work, because a type has to be an instance of MyClass before it can be an instance of SubClass. So you make MyData an instance of MyClass.
instance MyClass MyData
Again, this raises an error, because foo is included in the minimal complete definition of MyClass. For your instance to work, you would have to manually define foo, thus defeating the purpose of the default declaration.
In short, there is no way to do this in basic Haskell98 (or Haskell2010, for that matter). Thankfully, however, GHC provides a useful extension called DefaultSignatures. So, using Daniel's example:
{-# LANGUAGE DefaultSignatures #-}
class MyClass a where
foo :: a -> [a]
default foo :: SubClass a => a -> [a]
foo param = [param]
class MyClass a => SubClass a where
bar :: a -> a
And now, you can define the instances and they will work as you would expect. The downside to this solution is that the default definition has to be defined in MyClass, but this is necessary. The definition of foo belongs to the definition of MyClass (or one of its instance declarations), so if you were able to define the default declaration of foo within the definition of SubClass, Haskell's type isolation would be broken.
This can be achieved with DefaultSignatures:
{-# LANGUAGE DefaultSignatures #-}
class MyClass a where
foo :: a -> [a]
default foo :: SubClass a => a -> [a]
foo param = [param]
class MyClass a => SubClass a where
bar :: a -> a
Testing it in ghci:
> instance MyClass Integer; instance SubClass Integer where bar = id
> foo 3
[3]

How can I find out which (concrete) types satisfy a set of typeclass constraints?

Given a number of typeclass constraints:
{-# LANGUAGE ConstraintKinds, MultiParamTypeClasses #-}
import Data.Array.Unboxed(Ix,IArray,UArray)
type IntLike a = (Ord a, Num a, Enum a, Show a, Ix a, IArray UArray a)
How can I find out which types satisfy IntLike, i.e. all the mentioned constraints jointly?
I can puzzle together the information needed from the output of ghci's :info command, and then doublecheck my work by calling (or having ghci typecheck)
isIntLike :: IntLike -> Bool
isIntLike = const True
at various types, e.g. isIntLike (3::Int).
Is there a way to get ghci to do this for me?
I'm currently interested in concrete types, but wouldn't mind having a more general solution which also does clever stuff with unifying contexts!
Community Wiki answer based on the comments:
You can do this using template haskell.
main = print $(reify ''Show >>= stringE . show).
This won't work for type synonyms - rather, reify returns the AST representing the type synonym itself, without expanding it. You can check for type synonyms which are constraints, extract the constraints of which that type synonym consists, and continue reifying those.

How to handle functions of a multi-parameter typeclass, who not need every type of the typeclass?

I've defined a typeclass similar to an interface with a bunch of functions required for my program. Sadly, it needs multiple polymorphic types, but not every function of this multi-parameter typeclass needs every type. GHC haunts me with undeduceable types and i can't get the code running.
A reduced example:
{-# LANGUAGE MultiParamTypeClasses #-}
class Foo a b where
-- ...
bar :: a -> ()
baz :: Foo a b => a -> ()
baz = bar
GHC says
Possible fix: add a type signature that fixes these type variable(s)
How can I do this for b? Especially when I want to keep b polymorphic. Only an instance of Foo should define what this type is.
This is impossible.
The underlying problem is that a multiparameter type class depends on every type parameter. If a particular definition in the class doesn't use every type parameter, the compiler will never be able to know what instance you mean, and you'll never even be able to specify it. Consider the following example:
class Foo a b where
bar :: String -> IO a
instance Foo Int Char where
bar x = return $ read x
instance Foo Int () where
bar x = read <$> readFile x
Those two instances do entirely different things with their parameter. The only way the compiler has to select one of those instances is matching both type parameters. But there's no way to specify what the type parameter is. The class is just plain broken. There's no way to ever call the bar function, because you can never provide enough information for the compiler to resolve the class instance to use.
So why is the class definition not rejected by the compiler? Because you can sometimes make it work, with the FunctionalDependencies extension.
If a class has multiple parameters, but they're related, that information can sometimes be added to the definition of the class in a way that allows a class member to not use every type variable in the class's definition.
class Foo a b | a -> b where
bar :: String -> IO a
With that definition (which requires the FunctionalDependencies extension), you are telling the compiler that for any particular choice of a, there is only one valid choice of b. Attempting to even define both of the above instances would be a compile error.
Given that, the compiler knows that it can select the instance of Foo to use based only on the type a. In that case, bar can be called.
Splitting it in smaller typeclasses might be sufficient.
{-# LANGUAGE MultiParamTypeClasses #-}
class Fo a => Foo a b where
-- ...
foo :: a -> b -> ()
class Fo a where
bar :: a -> ()
baz :: Foo a b => a -> ()
baz = bar
Assuming you really want to use more than one instance for a given a (and so cannot use functional dependencies as others mentioned), one possibility which may or may not be right for you is to use a newtype tagged with a "phantom" type used only to guide type selection. This compiles:
{-# LANGUAGE MultiParamTypeClasses #-}
newtype Tagged t a = Tagged { unTagged :: a } -- Also defined in the tagged package
-- on Hackage
class Foo a b where
bar :: Tagged b a -> ()
baz :: Foo a b => Tagged b a -> ()
baz = bar
Then you will be able to wrap your values in such a way that you can give an explicit type annotation to select the right instance.
Another way of refactoring multi-parameter type classes when they get awkward is to use the TypeFamilies extension. Like FunctionalDependencies, this works well when you can reframe your class as having only a single parameter (or at least, fewer parameter), with the other types that are different from instance to instance being computed from the actual class parameters.
Generally I've found whenever I thought I needed a multi-parameter type class, the parameters almost always varied together rather than varying independently. In this situation it's much easier to pick one as "primary" and use some system for determining the others from it. Functional dependencies can do this as well as type families, but many find type families a lot easier to understand.
Here's an example:
{-# LANGUAGE TypeFamilies, FlexibleInstances #-}
class Glue a where
type Glued a
glue :: a -> a -> Glued a
instance Glue Char where
type Glued Char = String
glue x y = [x, y]
instance Glue String where
type Glued String = String
glue x y = x ++ y
glueBothWays :: Glue a => a -> a -> (Glued a, Glued a)
glueBothWays x y = (glue x y, glue y x)
The above declares a class Glue of types that can be glued together with the glue operation, and that have a corresponding type which is the result of the "gluing".
I then declared a couple of instances; Glued Char is String, Glued String is also just String.
Finally I wrote a function to show how you use Glued when you're being polymorphic over the instance of Glue you're using; basically you "call" Glued as a function in your type signatures; this means glueBothWays doesn't "know" what type Glued a is, but it knows how it corresponds to a. You can even use Glued Char as a type, if you know you're gluing Chars but don't want to hard-code the assumption that Glued Char = String.

How do I write, "if typeclass a, then a is also an instance of b by this definition."

I have a typeclass MyClass, and there is a function in it which produces a String. I want to use this to imply an instance of Show, so that I can pass types implementing MyClass to show. So far I have,
class MyClass a where
someFunc :: a -> a
myShow :: a -> String
instance MyClass a => Show a where
show a = myShow a
which gives the error Constraint is no smaller than the instance head. I also tried,
class MyClass a where
someFunc :: a -> a
myShow :: a -> String
instance Show (MyClass a) where
show a = myShow a
which gives the error, ClassMyClass' used as a type`.
How can I correctly express this relationship in Haskell?
Thanks.
I should add that I wish to follow this up with specific instances of MyClass that emit specific strings based on their type. For example,
data Foo = Foo
data Bar = Bar
instance MyClass Foo where
myShow a = "foo"
instance MyClass Bar where
myShow a = "bar"
main = do
print Foo
print Bar
I wish to vigorously disagree with the broken solutions posed thus far.
instance MyClass a => Show a where
show a = myShow a
Due to the way that instance resolution works, this is a very dangerous instance to have running around!
Instance resolution proceeds by effectively pattern matching on the right hand side of each instance's =>, completely without regard to what is on the left of the =>.
When none of those instances overlap, this is a beautiful thing. However, what you are saying here is "Here is a rule you should use for EVERY Show instance. When asked for a show instance for any type, you'll need an instance of MyClass, so go get that, and here is the implementation." -- once the compiler has committed to the choice of using your instance, (just by virtue of the fact that 'a' unifies with everything) it has no chance to fall back and use any other instances!
If you turn on {-# LANGUAGE OverlappingInstances, IncoherentInstances #-}, etc. to make it compile, you will get not-so-subtle failures when you go to write modules that import the module that provides this definition and need to use any other Show instance. Ultimately you'll be able to get this code to compile with enough extensions, but it sadly will not do what you think it should do!
If you think about it given:
instance MyClass a => Show a where
show = myShow
instance HisClass a => Show a where
show = hisShow
which should the compiler pick?
Your module may only define one of these, but end user code will import a bunch of modules, not just yours. Also, if another module defines
instance Show HisDataTypeThatHasNeverHeardOfMyClass
the compiler would be well within its rights to ignore his instance and try to use yours.
The right answer, sadly, is to do two things.
For each individual instance of MyClass you can define a corresponding instance of Show with the very mechanical definition
instance MyClass Foo where ...
instance Show Foo where
show = myShow
This is fairly unfortunate, but works well when there are only a few instances of MyClass under consideration.
When you have a large number of instances, the way to avoid code-duplication (for when the class is considerably more complicated than show) is to define.
newtype WrappedMyClass a = WrapMyClass { unwrapMyClass :: a }
instance MyClass a => Show (WrappedMyClass a) where
show (WrapMyClass a) = myShow a
This provides the newtype as a vehicle for instance dispatch. and then
instance Foo a => Show (WrappedFoo a) where ...
instance Bar a => Show (WrappedBar a) where ...
is unambiguous, because the type 'patterns' for WrappedFoo a and WrappedBar a are disjoint.
There are a number of examples of this idiom running around in the the base package.
In Control.Applicative there are definitions for WrappedMonad and WrappedArrow for this very reason.
Ideally you'd be able to say:
instance Monad t => Applicative t where
pure = return
(<*>) = ap
but effectively what this instance is saying is that every Applicative should be derived by first finding an instance for Monad, and then dispatching to it. So while it would have the intention of saying that every Monad is Applicative (by the way the implication-like => reads) what it actually says is that every Applicative is a Monad, because having an instance head 't' matches any type. In many ways, the syntax for 'instance' and 'class' definitions is backwards.
(Edit: leaving the body for posterity, but jump to the end for the real solution)
In the declaration instance MyClass a => Show a, let's examine the error "Constraint is no smaller than the instance head." The constraint is the type class constraint to the left of '=>', in this case MyClass a. The "instance head" is everything after the class you're writing an instance for, in this case a (to the right of Show). One of the type inference rules in GHC requires that the constraint have fewer constructors and variables than the head. This is part of what are called the 'Paterson Conditions'. These exist as a guarantee that type checking terminates.
In this case, the constraint is exactly the same as the head, i.e. a, so it fails this test. You can remove the Paterson condition checks by enabling UndecidableInstances, most likely with the {-# LANGUAGE UndecidableInstances #-} pragma.
In this case, you're essentially using your class MyClass as a typeclass synonym for the Show class. Creating class synonyms like this is one of the canonical uses for the UndecidableInstances extension, so you can safely use it here.
'Undecidable' means that GHC can't prove typechecking will terminate. Although it sounds dangerous, the worst that can happen from enabling UndecidableInstances is that the compiler will loop, eventually terminating after exhausting the stack. If it compiles, then obviously typechecking terminated, so there are no problems. The dangerous extension is IncoherentInstances, which is as bad as it sounds.
Edit: another problem made possible by this approach arises from this situation:
instance MyClass a => Show a where
data MyFoo = MyFoo ... deriving (Show)
instance MyClass MyFoo where
Now there are two instances of Show for MyFoo, the one from the deriving clause and the one for MyClass instances. The compiler can't decide which to use, so it will bail out with an error message. If you're trying to make MyClass instances of types you don't control that already have Show instances, you'll have to use newtypes to hide the already-existing Show instances. Even types without MyClass instances will still conflict because the definition instance MyClass => Show a because the definition actually provides an implementation for all possible a (the context check comes in later; its not involved with instance selection)
So that's the error message and how UndecidableInstances makes it go away. Unfortunately it's a lot of trouble to use in actual code, for reasons Edward Kmett explains. The original impetus was to avoid specifying a Show constraint when there's already a MyClass constraint. Given that, what I would do is just use myShow from MyClass instead of show. You won't need the Show constraint at all.
I think it would be better to do it the other way around:
class Show a => MyClass a where
someFunc :: a -> a
myShow :: MyClass a => a -> String
myShow = show
You can compile it, but not with Haskell 98, You have to enable some language extensions :
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
-- at the top of your file
Flexible instances is there to allow context in instance declaration. I don't really know the meaning of UndecidableInstances, but I would avoid as much as I can.
As Ed Kmett pointed out, this is not possible at all for your case. If however you have access to the class you want to provide a default instance for, you can reduce the boilerplate to a minimum with a default implementation and constrain the input type with the default signature you need:
{-# LANGUAGE DefaultSignatures #-}
class MyClass a where
someFunc :: a -> Int
class MyShow a where
myShow :: a -> String
default myShow :: MyClass a => a -> String
myShow = show . someFunc
instance MyClass Int where
someFunc i = i
instance MyShow Int
main = putStrLn (myShow 5)
Note that the only real boilerplate (well, apart from the whole example) reduced to instance MyShow Int.
See aesons ToJSON for a more realistic example.
You may find some interesting answers in a related SO question: Linking/Combining Type Classes in Haskell

Resources