Reputation: 2472
Basically, I would like to be able to do something like this:
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE FlexibleInstances #-}
import GHC.TypeLits
newtype Foo (a::Nat) (b::Nat) c = Foo {getFoo :: c}
class Clz a where
instance Clz (Foo a (2*a) c) where
I.e., to make Foo a b
instance of Clz
only when a = 2*b
.
I understand that the problem is in the (2*a)
expression on the last line. When I try to compile it, I get:
• Illegal type synonym family application in instance:
Foo a (2 * a) c
• In the instance declaration for ‘Clz (Foo a (2 * a) c)’
Is there a way to overcome this? How would I need to change the syntax? Do I need more language extensions? I am using latest GHC (8.0.1).
Upvotes: 1
Views: 109
Reputation: 68152
You can use a type equivalence constraint (by enabling GADTs or type families):
instance (b ~ (2 * a)) => Clz (Foo a b c) where
This is a common technique for working with type families as seen in this other answer. That answer has a bit more explanation: this constraint doesn't mean exactly the same thing as the version you wanted, but will probably still work for your purposes.
Upvotes: 3