派生ADT的显示实例不适用于高级类型的家庭

问题描述 投票:0回答:1

我只是在Chris Done的ADT中使用默认示例gist available here,但遇到了一个问题:我的ADT(具有由更高种类类型的族定义的字段)不适用于派生的show实例。 GHC告诉我我需要派生一个Type Family的Show实例,但是我不确定该怎么做。到目前为止,这是我所拥有的,任何评论都将有所帮助。

在下面的示例中(使用ghc 8.8.1),目标是为Show定义ShowMe的实例,如果可能的话,使用派生。

{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE PartialTypeSignatures #-}
{-# LANGUAGE ConstraintKinds #-}

data Tag = A | B deriving (Show)

type family TF (p :: Tag) a where
  TF 'A a = ()
  TF 'B a = a

data ShowMe p = ShowMe
  { a :: !(TF p String)
  , b :: String
  }

main =  connect showMeDefaults { a = "some string" }
   where
     connect :: ShowMe B -> IO ()
     connect _ = pure ()
     showMeDefaults :: ShowMe A
     showMeDefaults = ShowMe { a = (), b = "asdf" }

-- This works to define Show
{-
instance Show (ShowMe p) where
  show _ = "hello"
-}
-- This instance is the line that causes an error
deriving instance Show (ShowMe p)

随后,我从GHC收到了一个我不熟悉的错误:

show_tf.hs:35:1: error:
    • No instance for (Show (TF p String))
        arising from a use of ‘showsPrec’
    • In the first argument of ‘(.)’, namely ‘(showsPrec 0 b1)’
      In the second argument of ‘(.)’, namely
        ‘((.)
            (showsPrec 0 b1)
            ((.)
               GHC.Show.showCommaSpace
               ((.)
                  (showString "b = ") ((.) (showsPrec 0 b2) (showString "}")))))’
      In the second argument of ‘(.)’, namely
        ‘((.)
            (showString "a = ")
            ((.)
               (showsPrec 0 b1)
               ((.)
                  GHC.Show.showCommaSpace
                  ((.)
                     (showString "b = ") ((.) (showsPrec 0 b2) (showString "}"))))))’
      When typechecking the code for ‘showsPrec’
        in a derived instance for ‘Show (ShowMe p)’:
        To see the code I am typechecking, use -ddump-deriv
   |
35 | deriving instance Show (ShowMe p)

如果我们使用ghc -ddump-deriv重新编译,将返回以下内容:

[1 of 1] Compiling Main             ( show_tf.hs, show_tf.o )

==================== Derived instances ====================
Derived class instances:
  instance GHC.Show.Show Main.Tag where
    GHC.Show.showsPrec _ Main.A = GHC.Show.showString "A"
    GHC.Show.showsPrec _ Main.B = GHC.Show.showString "B"


Derived type family instances:



==================== Filling in method body ====================
GHC.Show.Show [Main.Tag]
  GHC.Show.show = GHC.Show.$dmshow @(Main.Tag)



==================== Filling in method body ====================
GHC.Show.Show [Main.Tag]
  GHC.Show.showList = GHC.Show.$dmshowList @(Main.Tag)


Linking show_tf ...

从概念上讲,我认为我应该能够为TF派生一个Show实例,但是当我这样做时,我得到以下信息:

show_tf.hs:36:31: error:
    • Illegal type synonym family application ‘TF 'A a’ in instance:
        Show (TF 'A a)
    • In the stand-alone deriving instance for
        ‘(Show a) => Show (TF 'A a)’

   |
36 | deriving instance (Show a) => Show (TF 'A a)

如果我只是尝试自己为TF 'A a定义Show实例,也会出现此错误。我搜索了“非法类型同义词”,还没有想出解决这个问题的方法。

haskell types
1个回答
0
投票
您需要添加
© www.soinside.com 2019 - 2024. All rights reserved.