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 导入GHC.TypeLits中SingI类的实例_Haskell - Fatal编程技术网

Haskell 导入GHC.TypeLits中SingI类的实例

Haskell 导入GHC.TypeLits中SingI类的实例,haskell,Haskell,玩弄GHC.TypeLits我制作了这个代码 data A (a :: Symbol) = A type B a (b :: Symbol) (c :: Symbol) = A a class AC a where af :: (String, a) -- instance SingI a => AC (A a) where -- af = (fromSing (sing :: Sing a), A) instance (SingI a, SingI b, SingI c)

玩弄GHC.TypeLits我制作了这个代码

data A (a :: Symbol) = A
type B a (b :: Symbol) (c :: Symbol) = A a

class AC a where
  af :: (String, a)

-- instance SingI a => AC (A a) where
--   af = (fromSing (sing :: Sing a), A)

instance (SingI a, SingI b, SingI c) => AC (B a b c) where
  af = (fromSing (sing :: Sing c), A)
如果我尝试在某个地方调用af时出现以下错误,则无法编译:

No instance for (SingI Symbol c) arising from a use of `af'
Possible fix: add an instance declaration for (SingI Symbol c)
In the second argument of `($)', namely
  `(af :: (String, B "a" "b" "c"))'
In the second argument of `($)', namely
  `fst $ (af :: (String, B "a" "b" "c"))'
In a stmt of a 'do' block:
  print $ fst $ (af :: (String, B "a" "b" "c")) 
对于
instance SingI a=>AC(a)
它仍然可以正常工作。很明显,它与类型同义词有关,但我找不到对此的任何解释。我很高兴听到为什么它是这样工作的,有没有可能在类型同义词中添加一些标记之王

扩展,用于编译:

  DataKinds,
  KindSignatures,
  TypeSynonymInstances,
  ScopedTypeVariables,
  -- MultiParamTypeClasses,
  UndecidableInstances

从GHC用户指南,第节:

使用-XTypeSynonymInstances标志,实例头可以使用类型同义词。一如既往,使用类型同义词是编写类型同义词定义的RHS的简写

将此规则应用于实例声明将导致:

instance (SingI a, SingI b, SingI c) => AC (A a) where
  af = (fromSing (sing :: Sing c), A)
请注意,这与您为“A”编写的实例相同,但对
c
b
有约束,现在这些约束甚至不会出现在实例头中。当您尝试使用该实例时:

print $ fst $ (af :: (String, B "a" "b" "c")) 
这就转化为

print $ fst $ (af :: (String, A "a"))

编译器抱怨没有SingI符号c的
实例,因为它不知道
c
是什么。要编译此代码,您必须提供一个适用于所有c语言的
实例SingI(c::Symbol)
(您可以使用
FlexibleInstances
编写这样的实例,但它不会有用,因为您无法根据
c
进行选择)。如果不希望出现这种行为,可以使用新类型

来自GHC用户指南,章节:

使用-XTypeSynonymInstances标志,实例头可以使用类型同义词。一如既往,使用类型同义词是编写类型同义词定义的RHS的简写

将此规则应用于实例声明将导致:

instance (SingI a, SingI b, SingI c) => AC (A a) where
  af = (fromSing (sing :: Sing c), A)
请注意,这与您为“A”编写的实例相同,但对
c
b
有约束,现在这些约束甚至不会出现在实例头中。当您尝试使用该实例时:

print $ fst $ (af :: (String, B "a" "b" "c")) 
这就转化为

print $ fst $ (af :: (String, A "a"))

编译器抱怨没有SingI符号c的
实例,因为它不知道
c
是什么。要编译此代码,您必须提供一个适用于所有c语言的
实例SingI(c::Symbol)
(您可以使用
FlexibleInstances
编写这样的实例,但它不会有用,因为您无法根据
c
进行选择)。如果不希望出现这种行为,可以使用新类型

谢谢,现在清楚了。我在这里使用同义词的唯一原因是为了保持与原始类型的兼容性,对于原始类型,我已经有一些类的实例,但希望向该类型添加一些附加信息。谢谢,现在已经清楚了。我在这里使用同义词的唯一原因是保持与原始类型的兼容性,对于原始类型,我已经有一些类的实例,但希望向该类型添加一些附加信息。