Reputation: 3848
Is it possible to write something like:
data SomeData = SomeValue | (Integral a) => SomeConstructor a
And how exactly would one write this?
Upvotes: 4
Views: 698
Reputation: 13223
Yep, exactly as you want, but need to mention quantification:
{-# LANGUAGE ExistentialQuantification #-}
data SomeData = SomeValue
| forall a . Integral a => SomeConstructor a
Upvotes: 2
Reputation: 2731
This is similar to Daniel Pratt's answer, but the more typical approach is to leave off the type constraints on your data definition, like this:
data SomeData a = SomeValue
| SomeConstructor a
Instead, you should put the (Integral a)
constraint on any functions that require it, which you'd have to do even if you added the constraint to the data definition too. Putting the constraint on the data definition buys you nothing, but forces you to carry around the constraint on all uses of SomeData
, even those that don't care what a
is at all. See Chapter 10 of Real World Haskell for more.
Upvotes: 13
Reputation: 12077
You can do something like this:
data Integral a => SomeData a =
SomeValue
| SomeConstructor a
Upvotes: 0
Reputation: 38708
For example, using GADTs:
{-# LANGUAGE GADTs #-}
data SomeData
where
SomeValue :: SomeData
SomeConstructor :: Integral a => a -> SomeData
Example of usage:
*Main> :t SomeValue
SomeValue :: SomeData
*Main> :t SomeConstructor 15
SomeConstructor 15 :: SomeData
*Main> :t SomeConstructor "aaa"
<interactive>:1:0:
No instance for (Integral [Char])
arising from a use of `SomeConstructor' at <interactive>:1:0-20
Possible fix: add an instance declaration for (Integral [Char])
In the expression: SomeConstructor "aaa"
*Main> let x = SomeConstructor 15 in case x of { SomeConstructor p -> fromIntegral p :: Int }
15
Upvotes: 6