Variable Argument Constructors

Using several extensions, I can do something like this:

{-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE DataKinds #-}

type family TF (a :: Bool) where
  TF 'True = Int
  TF 'False = Double

data D a where
  D :: TF a -> D a

Note that the constructor Dcan work in two ways. Or:

D :: Int -> D 'True

or

D :: Double -> D 'False

Using this template, I can completely change the arguments to the constructor depending on its type, reusing its name.

However, I also need the number of arguments to depend on the name.

I know that I could just replace some arguments ()or Void, but I would rather delete them completely.

Is there any way to do this?

+6
source share
1 answer

, , @luqui , , ( ), :

{-# LANGUAGE TypeFamilies #-}

data D = Int2 Int Int
       | Double1 Double
       deriving (Show)

class D1 a where
  d :: a -> T2 a
type family T2 a where
  T2 Int = Int -> D
  T2 Double = D

instance D1 Int where
  d x = \y -> Int2 x y     -- or just `d = Int2`
instance D1 Double where
  d x = Double1 x          -- or just `d = Double1`

:

> d (2 :: Int) 3
Int2 2 3
> d (2 :: Double)
Double1 2.0
> 

, , :

data D = IntStringDouble Int String Double
       | Int2 Int Int
       | Double1 Double
       deriving (Show)

- :

T2 Int = a -> T3 a

T3 , , , RHS . , - .

, , , , .

+1

All Articles