the Coverage Condition fails - haskell

I have a very simple piece of code as follow:
{-# LANGUAGE
MultiParamTypeClasses,
FunctionalDependencies,
FlexibleInstances,
FlexibleContexts
#-}
class Graph g n e | g -> n e where
nodes :: g -> [n]
edge :: g -> (n,n) -> Maybe e
instance Graph g Int e where
nodes g = []
edge g (n1,n2) = Nothing
I got an error related to the Coverage Condition fails for one of the functional dependencies. Do I need to add -XUndecidableInstances to permit this? or how I can fix this problem? Thanks

The problem in your case is not Int but e. The Coverage Condition is documented in GHC's manual Sect. 7.6.3.2. Relaxed rules for instance contexts and says:
The Coverage Condition. For each functional dependency, tvsleft -> tvsright, of the class, every type variable in S(tvsright) must appear in S(tvsleft), where S is the substitution mapping each type variable in the class declaration to the corresponding type in the instance declaration.
What does it mean in practise? In your case, your functional dependency says g -> n e, which means that for each instance the types denoted by n and e are unique for the type denoted by g. Now let's say you're defining an instance
instance Graph SomeTypeG SomeTypeN SomeTypeE where
...
The coverage condition says that any type variable appearing in SomeTypeE or SomeTypeN must appear in SomeTypeG. What happens if it's not satisfied? Let's suppose a type variable a appears in SomeTypeE but not in SomeTypeG. Then for fixed SomeTypeG we would have an infinite number of possible instances by substituting different types for a.
In your case
instance Graph g Int e where
...
e is such a type variable, so by the Coverage Condition it must appear in g, which is not true. Because it doesn't appear there, your definition would imply that Graph g Int Int is an instances, Graph g Int (Maybe Char) is another instance, etc., contradicting the functional dependency that requires that there is precisely one.
If you had defined something like
instance Graph g Int Char where
then it would be OK, as there are no type variables in Int and Char. Another valid instance could be
instance Graph (g2 e) Int e where
where g2 is now of kind * -> *. In this case, e appears in g2 e, which satisfies the Coverage Condition, and indeed, e is always uniquely determined from g2 e.

Your functional dependency says that your choice of type g determines your node and element types n and e, respectively. Does it make sense, then, to say that all graph types g (knowing nothing about g) determine the node type to be Int?

Related

Splitting type-classes and their instances to the different submodules in Haskell

I am currently writing a small helper library and I've faced the problem of really huge source code in one of the modules.
Basically, I am declaring a new parametric type-class and want to implement it for two different monad stacks.
I've decided to split the declaration of type-class and its implementations to the different modules, but I'm constantly getting warnings about orphaned instances.
As I know, that might happen if it is possible to import a datatype without an instance, i.e. if they are in a different module. But I have both type declaration and instance implementation inside each module.
To simplify the whole example, here is what I have now:
First is the module, where I define a type-class
-- File ~/library/src/Lib/API.hs
module Lib.API where
-- Lots of imports
class (Monad m) => MyClass m where
foo :: String -> m ()
-- More functions are declared
Then the module with instance implementation:
-- File ~/library/src/Lib/FirstImpl.hs
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE FlexibleInstances #-}
module Lib.FirstImpl where
import Lib.API
import Data.IORef
import Control.Monad.Reader
type FirstMonad = ReaderT (IORef String) IO
instance MyClass FirstMonad where
foo = undefined
Both of them are listed in my project's .cabal file, it's also impossible to use FirstMonad without the instance because they are defined in one file.
However, when I launch ghci using stack ghci lib, I'm getting the next warning:
~/library/src/Lib/FirstImpl.hs:11:1: warning: [-Worphans]
Orphan instance: instance MyClass FirstMonad
To avoid this
move the instance declaration to the module of the class or of the type, or
wrap the type with a newtype and declare the instance on the new type.
|
11 | instance MyClass FirstMonad where
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^...
Ok, two modules loaded
What am I missing and is there any way to split type-class declarations and their implementations into the different submodules?
To avoid this, you can wrap type in newtype
newtype FirstMonad a = FirstMonad (ReaderT (IORef String) IO a)
But after deep considering you feel need orphan instances, you can suppress warnings:
{-# OPTIONS_GHC -fno-warn-orphans #-}
Detail
Coherence
For example, considering following definition for now:
data A = A
instance Eq A where
...
It can be regarded as type based overloading. In the above, Checking equality (==) is able to be used under various types:
f :: Eq a => a -> a -> a -> Bool
f x y z = x == y && y == z
g :: A -> A -> A -> Bool
g x y z = x == y && y == z
In definition of f, type a is abstract and under constraint Eq, but in g, type A is concrete. The former derives method from constrains, but Haskell also in the latter can derive. How to derive is to just elaborate Haskell into language which has no type class. This way is called dictionary passing.
class C a where
m1 :: a -> a
instance C A where
m1 x = x
f :: C a => a -> a
f = m1 . m1
It will be converted:
data DictC a = DictC
{ m1 :: a -> a
}
instDictC_A :: DictC A
instDictC_A = DictC
{ m1 = \x -> x
}
f :: DictC a -> a -> a
f d = m1 d . m1 d
As the above, make a data type called dictionary corresponds to a type class, and pass the value of the type.
Haskell has a constraint that a type may not be declared as an instance of a particular class more than once in the program. This causes various problems.
class C1 a where
m1 :: a
class C1 a => C2 a where
m2 :: a -> a
instance C1 Int where
m1 = 0
instance C2 Int where
m2 x = x + 1
f :: (C1 a, C2 a) => a
f = m2 m1
g :: Int
g = f
This code uses inheritance of type class. It derives following elaborated code.
{ m1 :: a
}
data DictC2 a = DictC2
{ superC1 :: DictC1 a
, m2 :: a -> a
}
instDictC1_Int :: DictC1 Int
instDictC1_Int = DictC1
{ m1 = 0
}
instDictC2_Int :: DictC2 Int
instDictC2_Int = DictC2
{ superC1 = instDictC1_Int
, m2 = \x -> x + 1
}
f :: DictC1 a -> DictC2 a -> a
f d1 d2 = ???
g :: Int
g = f instDictC1_Int instDictC2_Int
Well, what is definition of f going on? Actually, Definition's' are following:
f :: DictC1 a -> DictC2 a -> a
f d1 d2 = m2 d2 (m1 d1)
f :: DictC1 a -> DictC2 a -> a
f _ d2 = m2 d2 (m1 d1)
where
d1 = superC1 d2
Do you confirm it has no problem in typing? If Haskell can define Int as a instance of C1 repeatedly, superC1 in DictC2 will be filled in elaboration, the value will be probably defferent from DictC1 a passed to f when call g.
Let's see more example:
h :: (Int, Int)
h = (m1, m1)
Of course, elaboration is one:
h :: (Int, Int)
h = (m1 instDictC1_Int, m1 instDictC1_Int)
But if can define instance repeatedly, can also consider following elaboration:
h :: (Int, Int)
h = (m1 instDictC1_Int, m1 instDictC1_Int')
Hence, two same types are applied two different instances. For example, calling same function twice, but returns different value by different algorithm possibly.
The stated example is little bit exaggerated, though how about next example?
instance C1 Int where
m1 = 0
h1 :: Int
h1 = m1
instance C1 Int where
m1 = 1
h2 :: (Int, Int)
h2 = (m1, h1)
In this case, quite possibly use different instances m1 in h1 and m1 in h2.
Haskell often prefers to transformation based on equational reasoning, so it will be a problem that h1 is not able to be replaced directly to m1.
Generally, type system include resolving instances of type classes. In such a case, resolve instances when check types. And codes are elaborated by derivation tree made during checking types. Such transformation is sometimes adapted by besides type class, specifically, implicit type conversion, record type and so on. Then, these cases possibly cause the problem as the above. This problem can formalized following:
When convert derivation tree of type into language, in two different derivation tree of one type, results of conversion don't become semantically equivalent.
As the stated, even apply whatever instance matches type, and it generally must pass type checking. However, a result of elaboration by using a instance is possibly different a result of elaboration after resolving other instance. Vice versa, if don't have this problem, can acquire certain guarantee of type system. This guarantee, a combination of type system which the problem formalized above doesn't work and property pf elaboration, is generally called coherence. There are some way to guarantee coherence, Haskell limits number of instance definition corresponding type class to one in order to guarantee coherence.
Orphan Instance
How Haskell does is easy to say, but has some issues. Quite famous one is orphan instance. GHC, in a type declaration T as an instance of C, treatment of instance depends on whether or not the declaration is in a same module which has declaration T or C. Especially, not in same module, called orphan instance, GHC will warn. Why how it works?
First, in Haskell, instances propagate implicitly between modules. This is stipulated as following:
All instances in scope within a module are always exported and any import brings all instances in from the imported module. Thus, an instance declaration is in scope if and only if a chain of import declarations leads to the module containing the instance declaration.
--5 Modules
We can't stop this, can't control this. In the first place, Haskell decided to let us define one type as one instance, so it's unnecessary to mind it. By the way, it's as good there is such regulation, actually compiler of Haskell must resolve instances according to the regulation. Of course, compiler doesn't know which modules have instances, must check all modules at worst case. It also bothers us. If two important modules hold each instance definition toward same type, all modules which have their import chains include the modules become unavailable in order to conflict.
Well, to use a type as a instance of a class, we need information of them, so we will go to see a module which has declarations. Then, that a third party fiddles the module is not going to happen. Therefore, if either of the modules includes the instance declaration, compiler can see necessary information with instances, we are happy that enable to load modules guarantees that they have no conflicts. For that reason, that a type as an instance of a class placed in a same module which has declaration the type or the class is being recommended. On the contrary, avoiding orphan instance as much as possible is being recommended. Hence, if want to make a type as a independent instance, making a new type by newtype in order to only change semantics of a instance, declaring the type as the instance.
In addition, GHC marks up internally modules have orphan instances, modules have orphan instances are enumerated in their dependent modules' interface files. And then, compiler refers all of the list. Thus, to make orphan instance once, an interface file of a module which has the instance, when all modules depend on the module recompile, will reloaded if whatever changes. So, orphan instance affects bad to compile time.
Detail is under CC BY-SA 4.0 (C) Mizunashi Mana
Original is 続くといいな日記 – 型クラスの Coherence と Orphan Instance
2020-12-22 revised and translated by Akihito Kirisaki

MultiParamTypeClasses - Why is this type variable ambiguous?

Suppose I define a multi-parameter type class:
{-# LANGUAGE MultiParamTypeClasses, AllowAmbiguousTypes, FlexibleContexts, FlexibleInstances #-}
class Table a b c where
decrement :: a -> a
evalutate :: a -> b -> c
Then I define a function that uses decrement, for simplicity:
d = decrement
When I try to load this in ghci (version 8.6.3):
• Could not deduce (Table a b0 c0)
arising from a use of ‘decrement’
from the context: Table a b c
bound by the type signature for:
d :: forall a b c. Table a b c => a -> a
at Thing.hs:13:1-28
The type variables ‘b0’, ‘c0’ are ambiguous
Relevant bindings include d :: a -> a (bound at Thing.hs:14:1)
These potential instance exist:
instance Table (DummyTable a b) a b
This is confusing to me because the type of d is exactly the type of decrement, which is denoted in the class declaration.
I thought of the following workaround:
data Table a b = Table (a -> b) ((Table a b) -> (Table a b))
But this seems notationally inconvenient, and I also just wanted to know why I was getting this error message in the first place.
The problem is that, since decrement only requires the a type, there is no way to figure out which types b and c should be, even at the point where the function is called (thus solving the polymorphism into a specific type) - therefore, GHC would be unable to decide which instance to use.
For example: let's suppose you have two instances of Table: Table Int String Bool, and Table Int Bool Float; you call your function d in a context where it is supposed to map an Int to another Int - problem is, that matches both instances! (a is Int for both).
Notice how, if you make your function equal to evalutate:
d = evalutate
then the compiler accepts it. This is because, since evalutate depends on the three type parameters a, b, and c, the context at the call site would allow for non-ambiguous instance resolution - just check which are the types for a, b, and c at the place where it is called.
This is, of course, not usually a problem for single-parameter type classes - only one type to resolve; it is when we deal with multiple parameters that things get complicated...
One common solution is to use functional dependencies - make b and c depend on a:
class Table a b c | a -> b c where
decrement :: a -> a
evalutate :: a -> b -> c
This tells the compiler that, for every instance of Table for a given type a, there will be one, and only one, instance (b and c will be uniquely determined by a); so it will know that there won't be any ambiguities and accept your d = decrement happily.

How to define a function inside haskell newtype?

I am trying to decipher the record syntax in haskell for newtype and my understanding breaks when there is a function inside newtype. Consider this simple example
newtype C a b = C { getC :: (a -> b) -> a }
As per my reasoning C is a type which accepts a function and a parameter in it's constructor.
so,
let d1 = C $ (2 *) 3
:t d1 also gives
d1 :: Num ((a -> b) -> a) => C a b
Again to check this I do :t getC d1, which shows this
getC d1 :: Num ((a -> b) -> a) => (a -> b) -> a
Why the error if I try getC d1? getC should return the function and it's parameter or at least apply the parameter.
I can't have newtype C a b = C { getC :: (a->b)->b } deriving (Show), because this won't make sense!
It's always good to emphasise that Haskell has two completely separate namespaces, the type language and the value language. In your case, there's
A type constructor C :: Type -> Type -> Type, which lives in the type language. It takes two types a, b (of kind Type) and maps them to a type C a b (also of kind Type)†.
A value constructor C :: ((a->b) -> a) -> C a b, which lives in the value language. It takes a function f (of type (a->b) -> a) and maps it to a value C f (of type C a b).
Perhaps it would be less confusing if you had
newtype CT a b = CV ((a->b) -> a)
but because for a newtype there is always exactly one value constructor (and exactly one type constructor) it makes sense to name them the same.
CV is a value constructor that accepts one function, full stop. That function will have signature (a->b) -> a, i.e. its argument is also a function, but as far as CT is concerned this doesn't really matter.
Really, it's kind of wrong that data and newtype declarations use a = symbol, because it doesn't mean the things on the left and right are “the same” – can't, because they don't even belong to the same language. There's an alternative syntax which expresses the relation better:
{-# LANGUAGE GADTs #-}
import Data.Kind
data CT :: Type -> Type -> Type where
CV :: ((a->b) -> a) -> CT a b
As for that value you tried to construct
let d1 = CV $ (\x->(2*x)) 3
here you did not pass “a function and a parameter” to CV. What you actually did‡ was, you applied the function \x->2*x to the value 3 (might as well have written 6) and passed that number to CV. But as I said, CV expects a function. What then happens is, GHC tries to interpret 6 as a function, which gives the bogus constraint Num ((a->b) -> a). What that means is: “if (a->b)->a is a number type, then...”. Of course it isn't a number type, so the rest doesn't make sense either.
†It may seem redundant to talk of “types of kind Type”. Actually, when talking about “types” we often mean “entities in the type-level language”. These have kinds (“type-level types”) of which Type (the kind of (lifted) value-level values) is the most prominent, but not the only one – you can also have type-level numbers and type-level functions – C is indeed one.Note that Type was historically written *, but this notation is deprecated because it's inconsistent (confusion with multiplication operator).
‡This is because $ has the lowest precedence, i.e. the expression CV $ (\x->(2*x)) 3 is actually parsed as CV ((\x->(2*x)) 3), or equivalently let y = 2*3 in CV y.
As per my reasoning C is a type which accepts a function and a parameter
How so? The constructor has only one argument.
Newtypes always have a single constructor with exactly one argument.
The type C, otoh, has two type parameters. But that has nothing to do with the number of arguments you can apply to the constructor.

Can GADTs be used to prove type inequalities in GHC?

So, in my ongoing attempts to half-understand Curry-Howard through small Haskell exercises, I've gotten stuck at this point:
{-# LANGUAGE GADTs #-}
import Data.Void
type Not a = a -> Void
-- | The type of type equality proofs, which can only be instantiated if a = b.
data Equal a b where
Refl :: Equal a a
-- | Derive a contradiction from a putative proof of #Equal Int Char#.
intIsNotChar :: Not (Equal Int Char)
intIsNotChar intIsChar = ???
Clearly the type Equal Int Char has no (non-bottom) inhabitants, and thus semantically there ought to be an absurdEquality :: Equal Int Char -> a function... but for the life of me I can't figure out any way to write one other than using undefined.
So either:
I'm missing something, or
There is some limitation of the language that makes this an impossible task, and I haven't managed to understand what it is.
I suspect the answer is something like this: the compiler is unable to exploit the fact that there are no Equal constructors that don't have a = b. But if that is so, what makes it true?
Here's a shorter version of Philip JF's solution, which is the way dependent type theorists have been refuting equations for years.
type family Discriminate x
type instance Discriminate Int = ()
type instance Discriminate Char = Void
transport :: Equal a b -> Discriminate a -> Discriminate b
transport Refl d = d
refute :: Equal Int Char -> Void
refute q = transport q ()
In order to show that things are different, you have to catch them behaving differently by providing a computational context which results in distinct observations. Discriminate provides exactly such a context: a type-level program which treats the two types differently.
It is not necessary to resort to undefined to solve this problem. Total programming sometimes involves rejecting impossible inputs. Even where undefined is available, I would recommend not using it where a total method suffices: the total method explains why something is impossible and the typechecker confirms; undefined merely documents your promise. Indeed, this method of refutation is how Epigram dispenses with "impossible cases" whilst ensuring that a case analysis covers its domain.
As for computational behaviour, note that refute, via transport is necessarily strict in q and that q cannot compute to head normal form in the empty context, simply because no such head normal form exists (and because computation preserves type, of course). In a total setting, we'd be sure that refute would never be invoked at run time. In Haskell, we're at least certain that its argument will diverge or throw an exception before we're obliged to respond to it. A lazy version, such as
absurdEquality e = error "you have a type error likely to cause big problems"
will ignore the toxicity of e and tell you that you have a type error when you don't. I prefer
absurdEquality e = e `seq` error "sue me if this happens"
if the honest refutation is too much like hard work.
I don't understand the problem with using undefined every type is inhabited by bottom in Haskell. Our language is not strongly normalizing... You are looking for the wrong thing. Equal Int Char leads to type errors not nice well kept exceptions. See
{-# LANGUAGE GADTs, TypeFamilies #-}
data Equal a b where
Refl :: Equal a a
type family Pick cond a b
type instance Pick Char a b = a
type instance Pick Int a b = b
newtype Picker cond a b = Picker (Pick cond a b)
pick :: b -> Picker Int a b
pick = Picker
unpick :: Picker Char a b -> a
unpick (Picker x) = x
samePicker :: Equal t1 t2 -> Picker t1 a b -> Picker t2 a b
samePicker Refl x = x
absurdCoerce :: Equal Int Char -> a -> b
absurdCoerce e x = unpick (samePicker e (pick x))
you could use this to create the function you want
absurdEquality e = absurdCoerce e ()
but that will produce undefined behavior as its computation rule. false should cause programs to abort, or at the very least run for ever. Aborting is the computation rule that is akin to turning minimal logic into intiutionistic logic by adding not. The correct definition is
absurdEquality e = error "you have a type error likely to cause big problems"
as to the question in the title: essentially no. To the best of my knowledge, type inequality is not representable in a practical way in current Haskell. Coming changes to the type system may lead to this getting nicer, but as of right now, we have equalities but not inequalites.

How can I combine two type constraints with a logical or in Haskell?

In Haskell we are given the ability to combine constraints on types with a logical and.
Consider the following
type And (a :: Constraint) b = (a, b)
or more complicatedly
class (a, b) => And a b
instance (a, b) => And a b
I want to know how to logically or two constraints together in Haskell.
My closest attempt is this, but it doesn't quite work. In this attempt I reify type constraints with tags and than dereify them with implicit parameters.
data ROr a b where
L :: a => ROr a b
R :: b => ROr a b
type Or a b = (?choose :: ROr a b)
y :: Or (a ~ Integer) (Bool ~ Integer) => a
y = case ?choose of
L -> 4
x :: Integer
x = let ?choose = L in y
It almost works, but the user has to apply the final part, and the compiler should do that for me. As well, this case does not let one choose a third choice when both constraints are satisfied.
How can I logically or two constraints together?
I believe that there is no way to automatically pick an ROr a b; it would violate the open world assumption if, e.g. b was satisfied, but later a was satisfied as well; any conflict resolution rule would necessarily cause the addition of an instance to change the behaviour of existing code.
That is, picking R when b is satisfied but a is not breaks the open world assumption, because it involves deciding that an instance is not satisfied;1 even if you added a "both satisfied" constructor, you would be able to use it to decide whether an instance is not present (by seeing if you get an L or an R).
Therefore, I do not believe that such an or constraint is possible; if you can observe which instance you get, then you can create a program whose behaviour changes by adding an instance, and if you can't observe which instance you get, then it's pretty useless.
1 The difference between this and normal instance resolution, which can also fail, is that normally, the compiler cannot decide that a constraint is satisfied; here, you're asking the compiler to decide that the constraint cannot be satisfied. A subtle but important difference.
I came here to answer your question on the cafe. Not sure the q here is the same, but anyway ...
a type class with three parameters.
class Foo a b c | a b -> c where
foo :: a -> b -> c
instance Foo A R A where ...
instance Foo R A A where ...
In addition to the functional dependency I'd like to express that at least one of the parameters a and b is c,
import Data.Type.Equality
import Data.Type.Bool
class ( ((a == c) || (b == c)) ~ True)
=> Foo a b c | a b -> c where ...
You'll need a bunch of extensions switched on. In particular UndecidableSuperClasses, because the type family calls in the class constraint are opaque as far as GHC can see.
Your q here
How can I logically or two constraints together?
Is far more tricky. For the type equality approach, == uses a Closed Type Family. So you could write a Closed Type Family returning kind Constraint, but I doubt there's a general solution. For your Foo class:
type family AorBeqC a b c :: Constraint where
AorBeqC a b a = ()
AorBeqC a b c = (b ~ c)
class AorBeqC a b c => Foo a b c | a b -> c where ...
It's likely to have poor and non-symmetrical type improvement behaviour: if GHC can see that a, c are apart, it'll go to the second equation and use (b ~ c) to improve either; if it can't see they're apart nor that they're unifiable, it'll get stuck.
In general, as #ehird points out, you can't test whether a constraint is not satisfiable. Type equality is special.

Resources