haskellfunctional-dependenciestype-families# Converting Functional Dependency class to Type Family instances

Is it possible to create type family instances from a fundep class? For example, let's say that I have the class

```
class A a b | a -> b
```

with some instances (imported an external library) and want to create all corresponding instances for the type family

```
type family A' a :: *
```

such that `A' a ~ b`

iff `A a b`

, without having to manually copy and modify the instances from the external source.

How would I do that (if it is possible)?

My most promising attempt so far,

```
class A' a where
type A'_b a :: *
instance forall a b. A a b => A' a where
type A'_b a = b
```

gives the error message

```
The RHS of an associated type declaration mentions ‘b’
All such variables must be bound on the LHS
```

So, my guess is that the answer is no? :/

Solution

Don't overthink it.

```
class C a b | a -> b
instance C T U
```

roughly translates into

```
class C' a where
type B a
instance C' T where
type B T = U
```

They're semantically somewhat different, even though they behave in a similar way. `C`

is a two-parameter class, but its second parameter is uniquely determined by its first. `C'`

is a one-parameter class with an associated type. Associated types are interpreted as top-level axioms for FC's coercion system whereas fundeps basically just affect unification.

It is possible to convert between the two styles, but you have to use a `newtype`

to bind the variables in the `type`

equation.

```
newtype WrappedB a = WrappedB { unwrapB :: B a }
instance C' a => C a (WrappedB a) -- you can't use a type synonym family in an instance
newtype Wrap a b = Wrap { unWrap :: a }
instance C a b => C' (Wrap a b) where
type B (Wrap a b) = b -- b needs to be bound on the LHS of this equation
```

In general I don't advise writing the sort of generic instance you've attempted in your question, because such instances have a tendency to be overlapping.

Functional dependencies are less, um, weird than type families, though. All other things being equal I tend to prefer a fundep.

- Comparing lists in Haskell
- Is there a non-identity monad morphism M ~> M that is monadically natural in M?
- Problem with loading module ‘Distribution.Simple’
- Improving efficiency in Stirling numbers calculation
- Does sequencing an infinite list of IO actions by definition result in a never-ending action? Or is there a way to bail out?
- How to call pgQuery from postgresql-query?
- How to avoid whitespace after a tag (link) in Hamlet templates?
- Understanding type-directed resolution in Haskell with existential types
- Why is seq bad?
- Understanding bind function in Haskell
- How to create route that will trigger on any path in Servant?
- How do I use a global state in WAI middleware?
- nixos 23.11 cabal install mysql-simple problem - "Missing (or bad) C libraries"
- Is there a way to kill all forked threads in a GHCi session without restarting it?
- Why can an invalid list expression such as 2:1 be assigned to a variable, but not printed?
- Iterate over a type level list and call a function based on each type in the list
- How does this solution of Project Euler Problem 27 in the Haskell Wiki work?
- Why `Monad` is required to use `pure`?
- Can't do partial function definitions in GHCi
- recommended way to convert Double -> Float in Haskell
- Haskell profiling understanding cost centre summary for anonymous lambda
- Why is Haskell fully declarative?
- GHC Generating Redundant Core Operations
- Question about Event firing in reflex-frp
- Using Haskell's "Maybe", type declarations
- How can I elegantly invert a Map's keys and values?
- Why there is no output for wrapped IO in Haskell?
- What are the definitions of Weather and Memory in xmobar repo?
- Serializing a Data.Text value to a ByteString without unnecessary \NUL bytes
- Using Haskell with VS Code