Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.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-7.6相关类型的类实例_Haskell_Ghc_Dependent Type - Fatal编程技术网

Haskell ghc-7.6相关类型的类实例

Haskell ghc-7.6相关类型的类实例,haskell,ghc,dependent-type,Haskell,Ghc,Dependent Type,异构列表是ghc 7.6中新独立类型设施的示例之一: data HList :: [*] -> * where HNil :: HList '[] HCons:: a -> HList t -> HList (a ': t) 示例列表“li”可以很好地编译: li = HCons "Int: " (HCons 234 (HCons "Integer: " (HCons 129877645 HNil))) 显然,我们希望HList位于Show类中,但我只能提出以下使

异构列表是ghc 7.6中新独立类型设施的示例之一:

data HList :: [*] -> * where
  HNil :: HList '[]
  HCons:: a -> HList t -> HList (a ': t)
示例列表“li”可以很好地编译:

li  = HCons "Int: " (HCons 234 (HCons "Integer: " (HCons 129877645 HNil)))
显然,我们希望HList位于Show类中,但我只能提出以下使用相互递归约束(超类)的工作类实例化:

代码编译得很好,li显示正确。需要的编译标志是:

{-# LANGUAGE DataKinds, TypeOperators, KindSignatures, 
FlexibleContexts, GADTs, FlexibleInstances #-}
我尝试了以下更直接的定义的许多变体,但如果我不能理解ghc错误消息,它就无法编译:

instance Show (HList '[]) where 
  show HNil = "[]"

instance (Show a, Show (HList t)) => Show (HList (a ': t)) where
  show l  = "[" ++ (show' l) ++ "]" where  
    show' (HCons h s) = case s of
      HNil      -> show h
      HCons _ _ -> show h ++ ", " ++ (show' s)
一些Haskell/ghc专家可能会理解为什么这不起作用,我很乐意听到原因

多谢各位

汉斯·彼得


谢谢你,哈马尔,为你的两个很好的工作例子,改进了我的第一个例子

但我仍然不明白为什么我的第二个例子不起作用。您说“…show”只知道如何显示当前的元素类型,而不知道如何显示其余的元素类型。”但该注释是否也适用于以下(工作)代码:


正如Nathan在评论中所说,
show'
只知道如何显示当前的元素类型,而不知道如何显示其余的元素类型

在第一个示例中,我们可以通过为
show'
创建一个新的类型类来解决这个问题,尽管您只能使用一个
show
实例:

-- Specializing show' to HLists avoids needing a Show' (HList ts) constraint
-- here, which would require UndecidableInstances.
instance (Show' ts) => Show (HList ts) where
  show xs = "[" ++ show' xs ++ "]"

class Show' ts where
  show' :: HList ts -> String

instance Show' '[] where
  show' HNil = ""

instance (Show a, Show' ts) => Show' (a ': ts) where
  show' (HCons a s) = case s of
    HNil     -> show a
    HCons {} -> show a ++ ", " ++ show' s
将所有必要的
Show
约束放入
Show'
的另一种更为老练的方法是使用
ConstraintKinds
直接构建所有必要约束的列表

-- In addition to the extensions in the original code:
{-# LANGUAGE TypeFamilies, ConstraintKinds, UndecidableInstances #-}
import GHC.Exts

-- ShowTypes [a, b, c, ...] = (Show a, Show b, Show c, ...)
type family ShowTypes (a :: [*]) :: Constraint
type instance ShowTypes '[] = ()
type instance ShowTypes (a ': t) = (Show a, ShowTypes t) 

instance ShowTypes ts => Show (HList ts) where
  show xs = "[" ++ show' xs ++ "]"
    where
      show' :: ShowTypes ts => HList ts -> String
      show' HNil = ""
      show' (HCons h s) = case s of
        HNil     -> show h
        HCons {} -> show h ++ ", " ++ show' s

多亏了哈马尔的第二个解决方案,我现在可以提供一种更通用的方法,它适用于普通类(但我想他无论如何都有这个想法):


再次感谢您的大力帮助。

您是否尝试过
show'(HCons h HNil)=show h
show'(HCons h s)=show h++>,“++show's
show':对于所有的t。(Show a,Show(HList t))=>HList(a):t)->String
不提供任何约束,表明可以显示列表中的下一个元素。将其定义为
HCons\uu->show h++“,“++show s
可以工作,但格式与您原来的示例不同。dbaupp:是的,我尝试过,但Nathan的评论适用于我原来的非工作解决方案以及您的提案。但我真的不明白。(请看下面的原因。)@wurmli我将您的编辑添加到了Hammers对您问题的回答中。如果您想要求澄清,请在注释中的适当位置。@wurmli A
Show A,Show(HList t))
约束声明您可以
显示列表的开头和结尾。它没有说明任何关于第N个元素(其中N>0)的内容,只是头和尾。带约束类型的类型族(Hammar的示例)或助手类型类(您的替代解决方案)是解决这一问题的两种方法。重新审视您的第二种解决方案,我实际上不仅觉得它“不错”,而且完全回答了我的问题,一点也不粗鲁。我一直在寻找一种方法来表达约束,您可以将其表示为一个类型族。我曾希望能够用实例定义来表达超类型的归纳。再次感谢你的帮助。
-- Specializing show' to HLists avoids needing a Show' (HList ts) constraint
-- here, which would require UndecidableInstances.
instance (Show' ts) => Show (HList ts) where
  show xs = "[" ++ show' xs ++ "]"

class Show' ts where
  show' :: HList ts -> String

instance Show' '[] where
  show' HNil = ""

instance (Show a, Show' ts) => Show' (a ': ts) where
  show' (HCons a s) = case s of
    HNil     -> show a
    HCons {} -> show a ++ ", " ++ show' s
-- In addition to the extensions in the original code:
{-# LANGUAGE TypeFamilies, ConstraintKinds, UndecidableInstances #-}
import GHC.Exts

-- ShowTypes [a, b, c, ...] = (Show a, Show b, Show c, ...)
type family ShowTypes (a :: [*]) :: Constraint
type instance ShowTypes '[] = ()
type instance ShowTypes (a ': t) = (Show a, ShowTypes t) 

instance ShowTypes ts => Show (HList ts) where
  show xs = "[" ++ show' xs ++ "]"
    where
      show' :: ShowTypes ts => HList ts -> String
      show' HNil = ""
      show' (HCons h s) = case s of
        HNil     -> show h
        HCons {} -> show h ++ ", " ++ show' s
type family ConstrainedTypes (a :: [*]) (f :: * -> Constraint) :: Constraint
type instance ConstrainedTypes '[] b = ()
type instance ConstrainedTypes (a ': t) b = (b a, ConstrainedTypes t b) 

instance ConstrainedTypes ts Show => Show (HList ts) where
  show xs = "[" ++ show' xs ++ "]"
    where
      show' :: ConstrainedTypes ts Show => HList ts -> String
      show' HNil = ""
      show' (HCons h s) = case s of
        HNil     -> show h
        HCons {} -> show h ++ ", " ++ show' s