Haskell如何构造具有依赖类型的对象
我在数据“D”中使用了类型族来约束其中第一项的类型。 现在我需要从一些常用函数(如intermediate_func)创建类型为“db1”或“db2”的对象。但是下面的代码不起作用。 有什么建议吗?或者以另一种方式施加类似的约束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
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中,我们需要辅助的单例/类型类,这更麻烦。