具有可变数量参数的构造函数

时间:2017-06-06 03:06:49

标签: haskell gadt type-families

使用一些扩展程序,我可以这样做:

{-# 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

请注意,构造函数D可以以两种方式工作。之一:

D :: Int -> D 'True

D :: Double -> D 'False

使用这种模式,我可以根据它的类型完全改变构造函数的参数,同时重用它的名称。

但是,我也想要依赖它名称的参数数量。

我知道我可以用()Void替换一些参数,但我宁愿完全删除它们。

有没有这样做?

1 个答案:

答案 0 :(得分:1)

我不确定这是否正是@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具有多态性。也许其他人可以看到一种方式。

无论如何,它可能比它的价值更麻烦。