Automatic derivation of Data.Vector.Unbox with associated type synonyms

蓝咒 提交于 2019-12-05 06:44:29
reinerp

You're running into a few separate problems here:

The TH approach

Yes, class instances for associated type synonyms are illegal

It's true that you can't define class instances for associated type synonyms or type functions, and this is with good reason: the compiler can't tell whether they overlap. For instance:

type family F a
instance Eq (F Int)
instance Eq (F Bool)

Do these instances overlap? Given the above source code, we can't tell: it depends on how someone later defines instances for F. For instance, they could define

type instance F Int = Double
type instance F Bool = Double

and then the two instances of Eq would in fact be overlapping.

You're running into a problem with the vector-th-unbox package

If you look at the actual Unbox instance you want, you don't actually want an instance for IntType q; what you want is simply this:

instance (Unbox (IntType q), Foo q) => Unbox (Zq q) where
    ...

The problem is that the vector-th-unbox package forces you to use the fake type-class Unbox' to communicate the intermediate representation type (IntType q in your case), as a convenient way of abusing Template Haskell's syntax to pass in a type. And then GHC sees that you have written Unbox' (Zq q) (IntType q) and complains. I would suggest filing a bug for the vector-th-unbox package.

Unbox for Vector r

I think Louis Wasserman covered this.

The GeneralizedNewtypeDeriving approach

The specific compile error you're having is because GHC can't infer the appropriate context. For most problems similar to the one you're having, StandaloneDeriving language extension would solve your problem:

deriving instance Unbox (IntType q) => Unbox (Zq q)
deriving instance Unbox (IntType q) => M.MVector MVector (Zq q)
deriving instance Unbox (IntType q) => G.Vector Vector (Zq q)

But DON'T do this!

While GeneralizedNewtypeDeriving often does exactly what you want, it is broken in some fundamental ways, and the Unbox instance it produces is completely broken! So stick with the TH approach, after lobbying Liyang for a fix for your current problem.

I've changed the syntax in 4820b73, so you should be able to do what you want now:

derivingUnbox "Complex"
    [d| (Unbox a) ⇒ Complex a → (a, a) |]
    [| \ (r :+ i) → (r, i) |]
    [| \ (r, i) → r :+ i |]

I've also fixed the “xyz is not a (visible) method…” errors in fe37976, although it was possible to work around it with:

import qualified Data.Vector.Generic
import qualified Data.Vector.Generic.Mutable

Out now on Hackage. CC: @reinerp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!