Deriving Via: Cannot derive well-kinded instance - haskell

I am encountering this error when I try to derive an instance.
Cannot derive well-kinded instance of form ‘HFunctor (ControlFlowCMD ...)’
Class ‘HFunctor’ expects an argument of kind ‘(* -> *, *)
-> * -> *’
• In the newtype declaration for ‘ControlFlowCMD’
I am trying to do this:
newtype ControlFlowCMD fs a = ControlFlowCMD (ControlCMD fs a)
deriving HFunctor via (ControlCMD fs a)
You can see the data type and instance I am basing my type on and trying to derive here, on line 278. I am not that used to using deriving via - could anyone explain what this error means and how I would fix it?

The problem was that (* -> *, *) or, equivalently, (Type -> Type, Type) is a kind-level tuple, and one must enable the DataKinds and PolyKinds extensions in order to handle it. (I'm not completely sure why PolyKinds is needed though; maybe it's to allow more general kind inference.)
With datatypes having complex kinds, it's often a good idea to enable StandaloneKindSignatures and give the kind signature explicitly:
import Data.Kind
type ControlFlowCMD :: (Type -> Type, Type) -> Type -> Type
newtype ControlFlowCMD fs a = ...

Related

Using a default implementation of typeclass method to omit an argument

I want to be able to define a (mulit-parameter-) typeclass instance whose implementation of the class's method ignores one of its arguments. This can be easily done as follows.
instance MyType MyData () where
specific _ a = f a
As I'm using this pattern in several places, I tried to generalize it by adding a specialized class method and adequate default implementations. I came up with the following.
{-# LANGUAGE MultiParamTypeClasses, AllowAmbiguousTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
class MyType a b where
specific :: b -> a -> a
specific = const dontCare
dontCare :: a -> a
dontCare = specific (undefined :: b)
{-# MINIMAL specific | dontCare #-}
This however yields the error Could not deduce (MyType a b0) arising from a use of ‘dontCare’ [..] The type variable ‘b0’ is ambiguous. I don't see why the latter should be the case with the type variable b being scoped from the class signature to the method declaration. Can you help me understand the exact problem that arises here?
Is there another reasonable way to achieve what I intended, namely to allow such trimmed instances in a generic way?
The problem is in the default definition of specific. Let's zoom out for a second and see what types your methods are actually given, based on your type signatures.
specific :: forall a b. MyType a b => b -> a -> a
dontCare :: forall a b. MyType a b => a -> a
In the default definition of specific, you use dontCare at type a -> a. So GHC infers that the first type argument to dontCare is a. But nothing constrains its second type argument, so GHC has no way to select the correct instance dictionary to use for it. This is why you ended up needing AllowAmbiguousTypes to get GHC to accept your type signature for dontCare. The reason these "ambiguous" types are useful in modern GHC is that we have TypeApplications to allow us to fix them. This definition works just fine:
class MyType a b where
specific :: b -> a -> a
specific = const (dontCare #_ #b)
dontCare :: a -> a
dontCare = specific (undefined :: b)
{-# MINIMAL specific | dontCare #-}
The type application specifies that the second argument is b. You could fill in a for the first argument, but GHC can actually figure that one out just fine.

Could you write a type function to invert a constraint?

Is it possible to write a type function that would take a constraint like Show and return one that constrains the RHS to types that are not an instance of Show?
The signature would be something like
type family Invert (c :: * -> Constraint) :: * -> Constraint
No. It is a design principle of the language that you are never allowed to do this. The rule is if a program is valid, adding more instances should not break it. This is the open-world assumption. Your desired constraint is a pretty direct violation:
data A = A
f :: Invert Show a => a -> [a]
f x = [x]
test :: [A]
test = f A
Would work, but adding
instance Show A
would break it. Therefore, the original program should never have been valid in the first place, and therefore Invert cannot exist.
As HTNW answered, it is in general not supposed to be possible to assert that a type is not an instance of a class. However, it is certainly possible to assert for a concrete type that it's never supposed to be possible to have an instance of some class for it. An ad-hoc way would be this:
{-# LANGUAGE ConstraintKinds, KindSignatures, AllowAmbiguousTypes
, MultiParamTypeClasses, FlexibleInstances #-}
import GHC.Exts (Constraint)
class Non (c :: * -> Constraint) (t :: *) where
nonAbsurd :: c t => r
But this is unsafe – the only way to write an instance is, like,
instance Non Show (String->Bool) where
nonAbsurd = undefined
but then somebody else could come up with a bogus instance Show (String->Bool) and would then be able to use your nonAbsurd for proving the moon is made out of green cheese.
A better option to make an instance impossible is to “block” it: write that instance yourself “pre-emptively”, but in such a way that it's a type error to actually invoke it.
import Data.Constraint.Trivial -- from trivial-constraint
instance Impossible0 => Show (String->Bool) where
show = nope
Now if anybody tries to add that instance, or tries to use it, they'll get a clear compiler error.

Type Family Equivalent of `Eq`?

Type Families with Class shows:
As I incompletely understand, this slide shows 2 ways of implementing Eq: via a type class or type family.
I'm familiar with type classes and thus implemented MyEq:
class MyEq a where
eq :: a -> a -> Bool
But, when I tried to define the type family version, it failed to compile:
data Defined = Yes | No
type family IsEq (a :: *) :: Defined
due to:
TypeEq.hs:30:30: error:
• Type constructor ‘Defined’ cannot be used here
(Perhaps you intended to use DataKinds)
• In the kind ‘Defined’
Please explain how to implement the type family version of the Eq type class.
Also, it'd be helpful, please, to show an implementation of such a type family instance (if that's even the right word).
This is kind of neat, glad to have stumbled across this. For the interested, here is the slide deck and here is the paper. This is a usual case of needing some language extensions.
{-# LANGUAGE DataKinds, TypeFamilies, TypeOperators, ConstraintKinds #-}
data Defined = Yes | No
type family IsEq (a :: *) :: Defined
type Eq a = IsEq a ~ Yes
Then, the "implementation" of this are instances like
type instance IsEq () = Yes -- '()' is an instance of 'Eq'
type instance IsEq Int = Yes -- 'Int' is an instance of 'Eq'
type instance IsEq [a] = IsEq a -- '[a]' is an instance of 'Eq' is 'a' is
You can "try" them out at GHCi:
ghci> :kind! IsEq [Int]
IsEq [Int] :: Defined
= Yes
But the paper and slide deck doesn't really worry too much about actually providing an equality function. (It mentions storing it in a field of Yes). So, why is this interesting if it isn't even ready to provide class methods? Because
it makes for a better mechanism than overlapping classes
backtracking search is easier than with typeclasses
it makes it possible to fail early with nice error message (encoded as a field in the No constructor)
Try adding DataKinds As a language extension (i.e. to the top of the file under a "language" pragma) as the error message suggests.
I haven't watched the talk, but iiuc, Defined is just Bool, where Yes is True. So if you enable DataKinds, you can just use IsEq a ~ 'True (and the apostrophe before True just means "this is a type").
Some background: what this extension does is "raise" every value of any algebraic datatypes (i.e. Declared with data, but not GADTs, iiuc) into its own type; and then raises each type into its own kind (a "kind" in Haskell is the "type of types"), i.e. not of "kind *" (pronounced "kind star"), which is the kind of normal Haskell values that exist at runtime.
btw:
[Bool] :: * means that "a list of liens is a type". and [] :: * -> * means that the type constructor for lists has kind "type to type", i.e. "once you give List a single type, you get back a type".

What is Ord type?

Is every class not a type in Haskell :
Prelude> :t max
max :: Ord a => a -> a -> a
Prelude> :t Ord
<interactive>:1:1: Not in scope: data constructor ‘Ord’
Prelude>
Why does this not print Ord type signature ?
Okay, there's a couple of things going on here.
First when you write :t Ord you're looking for something called Ord in the value namespace; specifically it would have to be a constructor, since the name starts with a capital letter.
Haskell keeps types and values completely separate; there is no relationship between the name of a type and the names of a type's constructors. Often when there's only one constructor, people will use the same name as the type. An example being data Foo = Foo Int. This declares two new named entities: the type Foo and the constructor Foo :: Int -> Foo.
It's not really a good idea to think of it as just making a type Foo that can be used both in type expressions and to construct Foos. Because also common are declarations like data Maybe a = Nothing | Just a. Here there are 2 different constructors for Maybe a, and Maybe isn't a name of anything at all at the value level.
So just because you've seen Ord in a type expression doesn't mean that there is a name Ord at the value level for you to ask the type of with :t. Even if there were, it wouldn't necessarily be related top the type-level name Ord.
The second point that needs clarifying is that no, classes are not in fact types. A class is a set of types (which all support the interface defined in the class), but it is not a type itself.
In vanilla Haskell type classes are just "extra" things. You can declare them with a class declaration, instantiate them with an instance declaration, and use them in special syntax attached to types (the stuff left of the => arrow) as constraints on type variables. But they don't really interact with the rest of the language, and you cannot use them in the main part of a type signature (the stuff right of the `=> arrow).
However, with the ConstraintKinds extension on, type classes do become ordinary things that exist in the type namespace, just like Maybe. They are still not types in the sense that there can never be any values that have them as types, so you can't use Ord or Ord Int as an argument or return type in a function, or have a [Ord a] or anything like that.
In that they are a bit like type constructors like Maybe. Maybe is a name bound in the type namespace, but it is not a type as such; there are no values whose type is just Maybe, but Maybe can be used as part of an expression defining a type, as in Maybe Int.
If you're not familiar with kinds, probably ignore everything I've said from ConstraintKinds onwards; you'll probably learn about kinds eventually, but they're not a feature you need to know much about as a beginner. If you are, however, what ConstraintKinds does is make a special kind Constraint and have type class constraints (left of the => arrow) just be ordinary type-level things of kind Constraint instead of special purpose syntax. This means that Ord is a type-level thing, and we can ask it's kind with the :k command in GHCI:
Prelude> :k Ord
* -> Constraint
Which makes sense; max had type Ord a => a -> a -> a, so Ord a must have kind Constraint. If Ord can be applied to an ordinary type to yield a constraint, it must have kind * -> Constraint.
Ord isn't a type; it's a typeclass. Typeclasses allow you to associate supported operations with a given type (somewhat similar to interfaces in Java or protocols in Objective-C). A type (e.g. Int) being an "instance" of a typeclass (e.g. Ord) means that the type supports the functions of the Ord typeclass (e.g. compare, <, > etc.).
You can get most info about a typeclass using :i in ghci, which shows you the functions associated with the typeclass and which types are instances of it:
ghci > :i Ord
class Eq a => Ord a where
compare :: a -> a -> Ordering
(<) :: a -> a -> Bool
(>=) :: a -> a -> Bool
(>) :: a -> a -> Bool
(<=) :: a -> a -> Bool
max :: a -> a -> a
min :: a -> a -> a
-- Defined in ‘GHC.Classes’
instance Ord a => Ord (Maybe a) -- Defined in ‘Data.Maybe’
instance (Ord a, Ord b) => Ord (Either a b)
-- Defined in ‘Data.Either’
instance Ord Integer -- Defined in ‘integer-gmp:GHC.Integer.Type’
instance Ord a => Ord [a] -- Defined in ‘GHC.Classes’
...
Ord is not a type, but a typeclass. It does not have a type, but a kind:
Prelude> :k Ord
Ord :: * -> Constraint
Typeclasses are one of the wonderful things about Haskell. Check 'em out :-)
Not quite. You can impose type constraints, so Ord a => a is a type, but Ord a isn't. Ord a => a means "any type a with the constraint that it is an instance of Ord".
The error is because :t expects an expression. When GHCi tries to interpret Ord as an expression, the closest it can get to is a data constructor, since these are the only functions in Haskell that can start with capital letters.

Convert from type `T a` to `T b` without boilerplate

So, I have an AST data type with a large number of cases, which is parameterized by an "annotation" type
data Expr a = Plus a Int Int
| ...
| Times a Int Int
I have annotation types S and T, and some function f :: S -> T. I want to take an Expr S and convert it to an Expr T using my conversion f on each S which occurs within an Expr value.
Is there a way to do this using SYB or generics and avoid having to pattern match on every case? It seems like the type of thing that this is suited for. I just am not familiar enough with SYB to know the specific way to do it.
It sounds like you want a Functor instance. This can be automatically derived by GHC using the DeriveFunctor extension.
Based on your follow-up question, it seems that a generics library is more appropriate to your situation than Functor. I'd recommend just using the function given on SYB's wiki page:
{-# LANGUAGE DeriveDataTypeable, ScopedTypeVariables, FlexibleContexts #-}
import Data.Generics
import Unsafe.Coerce
newtype C a = C a deriving (Data,Typeable)
fmapData :: forall t a b. (Typeable a, Data (t (C a)), Data (t a)) =>
(a -> b) -> t a -> t b
fmapData f input = uc . everywhere (mkT $ \(x::C a) -> uc (f (uc x)))
$ (uc input :: t (C a))
where uc = unsafeCoerce
The reason for the extra C type is to avoid a problematic corner case where there are occurrences of fields at the same type as a (more details on the wiki). The caller of fmapData doesn't need to ever see it.
This function does have a few extra requirements compared to the real fmap: there must be instances of Typeable for a, and Data for t a. In your case t a is Expr a, which means that you'll need to add a deriving Data to the definition of Expr, as well as have a Data instance in scope for whatever a you're using.

Resources