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但我宁愿完全删除它们.
反正有没有这样做?
我不确定这是否正是 @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 具有多态性。也许其他人可以看到一种方法。
不管怎样,这可能带来的麻烦多于其价值。