Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell Sigma中的限制类型_Haskell_Dependent Type_Singleton Type - Fatal编程技术网

Haskell Sigma中的限制类型

Haskell Sigma中的限制类型,haskell,dependent-type,singleton-type,Haskell,Dependent Type,Singleton Type,我的typeX按种类S编制索引,其中有几个函数可用于X。例如,f将xs1转换为xs2(但在这个简化示例中,它不使用xs1) 现在我想定义一些函数,这些函数可能返回xs2或xs3,具体取决于它的参数。简单的方法是使用或 g1 :: Bool -> X S1 -> Either (X S2) (X S3) g1 True x = Left X g1 False x = Right X 但我不想采用这种方法,因为当函数返回更多类型时,我需要嵌套或s 另一种方法是像这样使用Sigma g2

我的type
X
按种类
S
编制索引,其中有几个函数可用于
X
。例如,
f
xs1
转换为
xs2
(但在这个简化示例中,它不使用
xs1

现在我想定义一些函数,这些函数可能返回
xs2
xs3
,具体取决于它的参数。简单的方法是使用

g1 :: Bool -> X S1 -> Either (X S2) (X S3)
g1 True x = Left X
g1 False x = Right X
但我不想采用这种方法,因为当函数返回更多类型时,我需要嵌套
s

另一种方法是像这样使用
Sigma

g2 :: Bool -> X S1 -> Sigma S (TyCon X)
g2 True x = SS2 :&: X
g2 False x = SS3 :&: X
但这并不表示
g2
只返回
xs2
xs3
。我可以通过在
X
周围引入一个包装器来表达这个想法

data Y (s :: S) where
    Y2 :: X S2 -> Y S2
    Y3 :: X S3 -> Y S3

singletons [d|
    type Z s = Y s
  |]

g3 :: Bool -> X S1 -> Sigma S ZSym0
g3 True x = SS2 :&: Y2 X
g3 False x = SS3 :&: Y3 X
但是为每个组合定义这些包装并在调用方站点上展开它们是很麻烦的。如果我可以使用
g2
方法直接限制类型就好了,例如,通过应用类型约束,但我不确定如何才能做到

如何使用
g2
方法直接限制类型


我将GHC 8.8.4与一起使用。

这个问题看起来过于简单和做作;如果有更具体的动机就好了。但这是一个黑暗中的镜头

我们可以在第一个组件上使用谓词定义
Sigma
的变体:

datasigmap(i::Type)(p::i~>Constraint)(f::i->Type)其中
(:&?:::(p@@x)=>Sing x->f x->SigmaP i p f
一些定义谓词的代码似乎不可避免:

data Y23::S~>约束
类型实例应用Y23 x=Y23_x
类型族Y23_x(x::S)::约束,其中
Y23_uS2=(()::约束)
Y23_uS3=(()::约束)
Y23_uuu=('True~'False)
但是现在我们可以使用
X

g3::Bool->xs1->SigmaP S Y23 X
g3真x=SS2:&?:x
g3假x=SS3:&?:x

另一种方法灵感来自。它类似于,但使用显式类型列表

{-# LANGUAGE DataKinds, GADTs, EmptyCase, InstanceSigs, PolyKinds, ScopedTypeVariables, TemplateHaskell, TypeApplications, TypeFamilies, TypeOperators, UndecidableInstances #-}

import Data.Kind
import Data.Singletons
import Data.Singletons.Prelude
import Data.Singletons.TH

singletons [d|
    data S = S1 | S2 | S3 | S4 deriving (Show, Eq)
  |]

data X (s :: S) = X

data SigmaL (l :: [s :: Type]) (t :: s ~> Type) where
    (:&!:) :: OneOf fst l => Sing (fst :: s) -> t @@ fst -> SigmaL l t

type family OneOf s l :: Constraint where
    OneOf s l = If (Elem s l) (() :: Constraint) ('True ~ 'False)

g5 :: Bool -> X S1 -> SigmaL '[S2, S3] (TyCon X)
g5 True x = SS2 :&!: X
g5 False x = SS3 :&!: X

使用类型列表,
g::Bool->xs1->OneOf'[xs2,xs3]
,对
OneOf
进行适当的定义怎么样?@luqui谢谢。我会试着写它,但如果你能给我一些关于这种实现的参考,我将不胜感激。谢谢。这是我脑子里想的东西,但我不知道怎么写。尽管我仍然需要为每种组合编写
Y23
Y23
,但我更喜欢这样而不是我的
g3
{-# LANGUAGE DataKinds, GADTs, EmptyCase, InstanceSigs, PolyKinds, ScopedTypeVariables, TemplateHaskell, TypeApplications, TypeFamilies, TypeOperators, UndecidableInstances #-}

import Data.Kind
import Data.Singletons
import Data.Singletons.Prelude
import Data.Singletons.TH

singletons [d|
    data S = S1 | S2 | S3 | S4 deriving (Show, Eq)
  |]

data X (s :: S) = X

data SigmaL (l :: [s :: Type]) (t :: s ~> Type) where
    (:&!:) :: OneOf fst l => Sing (fst :: s) -> t @@ fst -> SigmaL l t

type family OneOf s l :: Constraint where
    OneOf s l = If (Elem s l) (() :: Constraint) ('True ~ 'False)

g5 :: Bool -> X S1 -> SigmaL '[S2, S3] (TyCon X)
g5 True x = SS2 :&!: X
g5 False x = SS3 :&!: X