Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.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如何构造具有依赖类型的对象_Haskell_Dependent Type - Fatal编程技术网

Haskell如何构造具有依赖类型的对象

Haskell如何构造具有依赖类型的对象,haskell,dependent-type,Haskell,Dependent Type,我在数据“D”中使用了类型族来约束其中第一项的类型。 现在我需要从一些常用函数(如intermediate_func)创建类型为“db1”或“db2”的对象。但是下面的代码不起作用。 有什么建议吗?或者以另一种方式施加类似的约束 data A1 = A1 data A2 = A2 data B1 = B1 data B2 = B2 data C a b where C1 :: Int → C a b C2 :: Char → C A1 b C3 :: Bool → C A1

我在数据“D”中使用了类型族来约束其中第一项的类型。 现在我需要从一些常用函数(如intermediate_func)创建类型为“db1”或“db2”的对象。但是下面的代码不起作用。 有什么建议吗?或者以另一种方式施加类似的约束

data A1 = A1
data A2 = A2

data B1 = B1
data B2 = B2

data C a b where
  C1 :: Int →  C a b
  C2 :: Char →  C A1 b
  C3 :: Bool →  C A1 B1

type family ResT b where
  ResT B1 = C A1 B1
  ResT B2 = C A2 B2

data D b where
  D1 :: ResT B1 →  C A1 B1 →  D B1
  D2 :: ResT b →  C A1 b →  D b

-- This does not compile
intermediate_func :: Int →  D b
intermediate_func i = D2 (C1 i) (C1 i)

-- This works
-- intermediate_func :: Int -> D B2
-- intermediate_func i = D2 (C1 i) (C1 i)
-- So does this
-- intermediate_func :: Int -> D B1
-- intermediate_func i = D2 (C1 i) (C1 i)

您需要证明
b
B1
B2
,而不是其他任何东西。如前所述,可以调用
intermediate\u func::Int→  D字符串

你可以通过单身汉来证明:

data S b where
   SB1 :: S B1
   SB2 :: S B2

intermediate_func :: S b → Int →  D b
intermediate_func SB1 i = D2 (C1 i) (C1 i)
intermediate_func SB2 i = D2 (C1 i) (C1 i)
如果要隐藏类型为
sb
的单例参数,请签出。您可以使用类型类来实现这一点。例如

class CB b where getSB :: S b
instance CB B1 where getSB = SB1
instance CB B2 where getSB = SB2

intermediate_func :: SB b → Int → D b
intermediate_func SB1 i = D2 (C1 i) (C1 i)
intermediate_func SB2 i = D2 (C1 i) (C1 i)

intermediate_func_short :: CB b => Int → D b
intermediate_func_short = intermediate_func getSB

您需要证明
b
B1
B2
,而不是其他任何东西。如前所述,可以调用
intermediate\u func::Int→  D字符串

你可以通过单身汉来证明:

data S b where
   SB1 :: S B1
   SB2 :: S B2

intermediate_func :: S b → Int →  D b
intermediate_func SB1 i = D2 (C1 i) (C1 i)
intermediate_func SB2 i = D2 (C1 i) (C1 i)
如果要隐藏类型为
sb
的单例参数,请签出。您可以使用类型类来实现这一点。例如

class CB b where getSB :: S b
instance CB B1 where getSB = SB1
instance CB B2 where getSB = SB2

intermediate_func :: SB b → Int → D b
intermediate_func SB1 i = D2 (C1 i) (C1 i)
intermediate_func SB2 i = D2 (C1 i) (C1 i)

intermediate_func_short :: CB b => Int → D b
intermediate_func_short = intermediate_func getSB

使用类型类的解决方案:

{-# LANGUAGE GADTs #-}                                                                                             
{-# LANGUAGE TypeFamilies #-}                                                                                      
module Temp where                                                                                                  

data A1                                                                                                            
data A2                                                                                                            
data B1                                                                                                            
data B2                                                                                                            

data C a b where                                                                                                   
  C1 :: Int ->  C a b                                                                                              
  C2 :: Char ->  C A1 b                                                                                            
  C3 :: Bool ->  C A1 B1                                                                                           

class Intermediate b where                                                                                         
  type ResT b                                                                                                      
  intermediate_func :: Int ->  D b                                                                                 

data D b where                                                                                                     
  D1 :: ResT B1 ->  C A1 B1 ->  D B1                                                                               
  D2 :: ResT b ->  C A1 b ->  D b                                                                                  

instance Intermediate B1 where                                                                                     
  type ResT B1 = C A1 B1                                                                                           
  intermediate_func i = D2 (C1 i) (C1 i)                                                                           

instance Intermediate B2 where                                                                                     
  type ResT B2 = C A2 B2                                                                                           
  intermediate_func i = D2 (C1 i) (C1 i)                                                                           

使用类型类的解决方案:

{-# LANGUAGE GADTs #-}                                                                                             
{-# LANGUAGE TypeFamilies #-}                                                                                      
module Temp where                                                                                                  

data A1                                                                                                            
data A2                                                                                                            
data B1                                                                                                            
data B2                                                                                                            

data C a b where                                                                                                   
  C1 :: Int ->  C a b                                                                                              
  C2 :: Char ->  C A1 b                                                                                            
  C3 :: Bool ->  C A1 B1                                                                                           

class Intermediate b where                                                                                         
  type ResT b                                                                                                      
  intermediate_func :: Int ->  D b                                                                                 

data D b where                                                                                                     
  D1 :: ResT B1 ->  C A1 B1 ->  D B1                                                                               
  D2 :: ResT b ->  C A1 b ->  D b                                                                                  

instance Intermediate B1 where                                                                                     
  type ResT B1 = C A1 B1                                                                                           
  intermediate_func i = D2 (C1 i) (C1 i)                                                                           

instance Intermediate B2 where                                                                                     
  type ResT B2 = C A2 B2                                                                                           
  intermediate_func i = D2 (C1 i) (C1 i)                                                                           

谢谢你,池!这很有效。但我真的不想把它放在每个API中。所以使用类型类会更好。我试着用你在另一篇文章中给出的答案来实现一个,但仍然不明白如何实现:(你也可以用类型类来发布答案吗?我试着让这样的东西起作用
intermediate_func::(IsB)=>Int->D b
我想我理解为什么,但我仍然觉得@rampion确实有点令人失望。在真正的依赖类型语言中,您可以在类型上进行模式匹配。在Haskell中,我们需要辅助的单例/类型类,这更麻烦。谢谢chi!这很有效。但我真的不想在每个API中都使用它。所以我们使用类型类会更好。我尝试使用您在另一篇文章中给出的答案实现一个,但仍然不明白如何实现:(您也可以使用类型类发布答案吗?我尝试使用类似的方法
intermediate\u func:(IsB)=>Int->D b
我想我理解为什么,但我仍然觉得@rampion确实有点令人失望。在真正的依赖类型语言中,您可以在类型上进行模式匹配。在Haskell中,我们需要辅助的单例/类型类,这更麻烦。