Is it possible to write something like:
data SomeData = SomeValue | (Integral a) => SomeConstructor a
And how exactly would one write this?
Is it possible to write something like:
data SomeData = SomeValue | (Integral a) => SomeConstructor a
And how exactly would one write this?
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
You can do something like this:
data Integral a => SomeData a =
SomeValue
| SomeConstructor a
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.
Yep, exactly as you want, but need to mention quantification:
{-# LANGUAGE ExistentialQuantification #-}
data SomeData = SomeValue
| forall a . Integral a => SomeConstructor a