Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Which language extensions enable to write "class A (B c) => D c where ..." ? What is the meaning of this type class declaration?

I am trying to understand the following class declaration :

class (MonadHold t (PushM t), MonadSample t (PullM t), Functor (Event t), Functor (Behavior t)) => Reflex t where
  data Behavior t :: * -> *

which is in the Reflex FRP library.

1 ) What language extensions make it possible to write Functor (Behavior t) => Reflex t ? I guess it is a combination of Language extensions. I am guessing Type Families are involved, but what else ?

In other words, what language extension do I have to turn on such that a code containing class A (B c) => D c where ... compiles ?

2 ) What is the meaning of class A (B c) => D c where ... ?

3 ) Could you give a super simple example explaining why and when one wants to write class A (B c) => D c where ... ?

4 ) Where is it described what class A (B c) => D c where ... means ? I guess there is an SPJ paper or talk describing it could you please point to it ?

Edit:

Further related info:

Here it is written:

In Haskell 98 the context of a class declaration (which introduces superclasses) must be simple; that is, each predicate must consist of a class applied to type variables.

If I interpret the above citation correctly then in Haskell98 only class A b=>C b where shaped class declarations are allowed, which means that class A(B c) => D c is not allowed. So the question is, if the latter is allowed, and the former is not, who and what defines the MEANING for the latter ? The latter is not correct Haskell 98 syntax so its meaning is also not described in any Haskell 98 book, then where it is the MEANING of the latter described/documented/specified?

like image 350
jhegedus Avatar asked Feb 09 '23 15:02

jhegedus


2 Answers

First of all, as you've correctly guessed, Behaviour is an associated data type, so falls under the TypeFamilies extension.

The point of class Functor (Behaviour t) => Reflex t where data Behaviour t :: * -> * is to enforce the requirement that for any type t which is an instance of Reflex, whatever datatype you define as the associated data type Behaviour t, you must also make that type into an instance of Functor.

Here's a small example: suppose I this class definition:

{-# LANGUAGE TypeFamilies, FlexibleContexts #-}

class Functor (F a) => Funky a where
    data F a :: * -> *

This allows writing something like

frobulate :: (Funky a) => F a Int -> F a Bool
frobulate = fmap (< 5)

since frobulate is free to assume from Funky a that Functor (F a).

The following by itself is rejected by the type checker:

instance Funky Int where
    data F Int a = MkF a

because the associated datatype F Int is not an instance of Functor:

No instance for (Functor (F Int))
  arising from the superclasses of an instance declaration
In the instance declaration for `Funky Int'

which forces you to also add an instance definition like

instance Functor (F Int) where
    fmap f (MkF x) = MkF (f x)

Note that the latter Functor instance also requires FlexibleInstances to be turned on.

like image 77
Cactus Avatar answered Mar 23 '23 00:03

Cactus


For part 4: the Haskell Report says:

Assume that the type variables in the instance type (T u1 … uk) satisfy the constraints in the instance context cx′. Under this assumption, the following two conditions must also be satisfied:

  1. The constraints expressed by the superclass context cx[(T u1 … uk)/u] of C must be satisfied. In other words, T must be an instance of each of C's superclasses and the contexts of all superclass instances must be implied by cx′.
  2. Any constraints on the type variables in the instance type that are required for the class method declarations in d to be well-typed must also be satisfied.

None of this discussion assumes that superclass contexts are of the simplified form demanded elsewhere in the report; and therefore can (and does) serve as the meaning of more complicated superclass contexts.

like image 22
Daniel Wagner Avatar answered Mar 22 '23 23:03

Daniel Wagner