Julian Birch
Julian Birch

Reputation: 2768

Way to have a common function in an instance declaration?

I'm trying to make the following code work:

instance (Integral n, OffsetCalculator o, HexDirection d) => (IsoEvidence (Axial d n) (Offset d o n)) where
    po :: Proxy o
    po = Proxy
    pd :: Proxy d
    pd = Proxy
    adj :: Vector2D n -> n
    adj p = adjustment po $ p ^. otherAxis pd
    convert :: (n -> n -> n) -> Vector2D n -> Vector2D n
    convert f p = (offsetAxis pd) %~ (flip f (adj p)) $ p

    convertFrom (Offset p) = Axial $ convert (P.-) p
    convertTo (Axial p) = Offset $ convert (P.+) p

I'm converting this from some previously compiling code, so I'm relatively confident the code is conceptually fine. My problem is that convertFrom and convertTo are the only exposed methods of the IsoEvidence class. Therefore, the rest of this doesn't compile.

If I move "convert" out of the instance declaration, it starts to need Proxy parameters itself which makes the code uglier. Is there a way to make what I'm trying to do work?

Upvotes: 0

Views: 63

Answers (1)

dfeuer
dfeuer

Reputation: 48611

Haskell doesn't allow local definitions in instance declaration where clauses. But suppose, hypothetically, that it did. Then what you're trying to do still wouldn't work. The compiler has no way to know how to instantiate the type variables in the calls to convert. You seem to want something like implicit parameters at the type level, and that sounds like an absolute nightmare to me. If proxy passing isn't to your taste, you can use TypeApplications instead.

Upvotes: 1

Related Questions