gpt4 book ai didi

haskell - 依赖类型的 ghc-7.6 类实例

转载 作者:行者123 更新时间:2023-12-04 11:55:50 24 4
gpt4 key购买 nike

异构列表是 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 类中,但我只能提出以下使用相互递归约束(父类(super class))的工作类实例:
instance Show (HList '[]) where 
show HNil = "[]"

instance (Show a, Show' (HList t)) => Show (HList (a ': t)) where
show l = "[" ++ show' l ++ "]"

class Show' a where
show' :: a -> String

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

instance (Show a, Show' (HList t)) => Show' (HList (a ': t)) where
show' (HCons h l) = case l of
HNil -> show h
HCons _ _ -> show h ++ ", " ++ (show' l)

代码编译良好,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 专家可能会理解为什么这不起作用,我很乐意听到原因。

谢谢

汉斯·彼得

谢谢你,hammar,你的两个很好的工作示例,改进了我的第一个示例。

但我仍然不明白为什么我的第二个例子不起作用。您说“... show' 只知道如何显示当前元素类型,而不知道如何显示其余元素类型。”但是该评论是否也不适用于以下(工作)代码:
instance Show (HList '[]) where show HNil = "" 

instance (Show a, Show (HList t)) => Show (HList (a ': t)) where
show (HCons h t) = case t of
HNil -> show h
HCons _ _ -> show h ++ ", " ++ (show t)

最佳答案

正如 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

关于haskell - 依赖类型的 ghc-7.6 类实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12989389/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com