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

Cli*_*ton 6 haskell type-families gadt

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

{-# 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
Run Code Online (Sandbox Code Playgroud)

请注意,构造函数D可以以两种方式工作.或者:

D :: Int -> D 'True
Run Code Online (Sandbox Code Playgroud)

要么

D :: Double -> D 'False
Run Code Online (Sandbox Code Playgroud)

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

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

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

反正有没有这样做?

K. *_*uhr 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`
Run Code Online (Sandbox Code Playgroud)

之后:

> d (2 :: Int) 3
Int2 2 3
> d (2 :: Double)
Double1 2.0
> 
Run Code Online (Sandbox Code Playgroud)

我不清楚如何将其推广到需要条件调度的情况:

data D = IntStringDouble Int String Double
       | Int2 Int Int
       | Double1 Double
       deriving (Show)
Run Code Online (Sandbox Code Playgroud)

因为你需要类似的东西:

T2 Int = a -> T3 a
Run Code Online (Sandbox Code Playgroud)

在调度的下一步中使用T3额外的类型系列,并且我认为没有任何方法可以使类型系列的 RHS 具有多态性。也许其他人可以看到一种方法。

不管怎样,这可能带来的麻烦多于其价值。