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 定义了一个类型族(+;+;);有没有办法证明(与我们相比)&+;x27;[]意味着(vs~';[])和(us~';[])?_Haskell_Functional Dependencies_Type Families - Fatal编程技术网

Haskell 定义了一个类型族(+;+;);有没有办法证明(与我们相比)&+;x27;[]意味着(vs~';[])和(us~';[])?

Haskell 定义了一个类型族(+;+;);有没有办法证明(与我们相比)&+;x27;[]意味着(vs~';[])和(us~';[])?,haskell,functional-dependencies,type-families,Haskell,Functional Dependencies,Type Families,定义: type family (xs :: [*]) ++ (ys :: [*]) where '[] ++ ys = ys (x ': xs) ++ ys = x ': (xs ++ ys) 我有一个有点像 data Foo :: [*] -> * -> * where Foo0 :: a -> Foo '[] a Foo1 :: Foo '[a] a Foo2 :: Foo vs a -> Foo us a -> Foo (vs ++ u

定义:

type family (xs :: [*]) ++ (ys :: [*]) where
  '[] ++ ys = ys
  (x ': xs) ++ ys = x ': (xs ++ ys)
我有一个有点像

data Foo :: [*] -> * -> * where
  Foo0 :: a -> Foo '[] a
  Foo1 :: Foo '[a] a
  Foo2 :: Foo vs a -> Foo us a -> Foo (vs ++ us) a
我想做一些类似的事情

test :: Foo '[] Int -> Int
test (Foo0 x) = x
test (Foo2 x y) = test x + test y
但是我不能在
x
y
上使用
test
,因为
x~Foo'[]Int
y~Foo'[]Int
必须经过验证。但是我想说的是,事实证明了这一点,
vs++us~'[]
意味着
vs
us
中的
x
y
的个体必然是
'[]

有没有办法用类型族实现这一点,或者用fundeps切换到多参数类型类方法

谢谢

返回类型中存在“green slime”定义的函数 对施工人员来说,这是一个危险的标志

最简单的解决方法是概括
测试
,然后实例化:

gtest :: Foo xs Int -> Int
gtest (Foo0 x) = x
gtest (Foo2 x y) = gtest x + gtest y

test :: Foo '[] Int -> Int
test = gtest

您可以添加两个类型族,作为
++
的逆类型,并在不丧失通用性的情况下将它们作为约束添加到Foo2构造函数中。通过这些反向类型的族,GHC将能够准确地推断出您从中提出的要求

下面是
CutX
CutY
的示例实现,这样
ra++b
a~CutY rb
b~CutX ra

type family (xs :: [*]) ++ (ys :: [*]) where
  '[] ++ ys = ys
  (x ': xs) ++ ys = x ': (xs ++ ys)

type family CutX (rs :: [*]) (xs :: [*]) where
    CutX '[] xs = '[]
    CutX rs '[] = rs
    CutX (r ': rs) (x ': xs) = CutX rs xs

type family ZipWithConst (xs :: [*]) (ys :: [*]) where
    ZipWithConst '[] ys = '[]
    ZipWithConst xs '[] = '[]
    ZipWithConst (x ': xs) (y ': ys) = y ': ZipWithConst xs ys

type CutY rs ys = ZipWithConst rs (CutX rs ys)

data Foo :: [*] -> * -> * where
  Foo0 :: a -> Foo '[] a
  Foo1 :: Foo '[a] a
  Foo2 :: (rs ~ (vs ++ us), us ~ CutX rs vs, vs ~ CutY rs us) => Foo vs a -> Foo us a -> Foo rs a

如果
[*]
索引始终等于
[*]
,为什么还要在
Foo
GADT中使用它呢?假设有另一个构造函数:)您还可以包括其他构造函数吗?当前的一组构造函数使我们的工作变得相当简单(参考下面的user3237465的答案)。@AndrásKovács啊,我明白你的意思。我又加了一个。。。这有区别吗?@AndrásKovács可能是以前从未使用过。不久前我自己发现了它并写了一篇文章。