解释通用类型不一致

问题描述

我试图按值获取数据构造函数名称。 我找到了解决方法here

{-# LANGUAGE DeriveGeneric,TypeFamilies,TypeOperators,FlexibleInstances,FlexibleContexts,UndecidableInstances #-}
import GHC.Generics
undef2 :: mi f p -> f p
undef2 _ = undefined
data Tt = Cc deriving (Show,Generic)
> conName $ undef2 (from Cc)
"Cc"

我以为这就是我所需要的,并试图将代码放在D1的类实例中。

>:t (from Cc)
from Cc
  :: D1
       ('MetaData "Tt" "Main" "main" 'False)
       (C1 ('MetaCons "Cc" 'PrefixI 'False) U1)
       x

我假设,如果“ from Cc”是D1,则D1的实现应该起作用。

class GDConstrName a where
  gname :: a x -> String

instance GDConstrName (D1 m x) where
  gname x = conName $ undef2 x

上面的代码段编译失败:

Main.hs:37:23: error:
    • Couldn't match type ‘x’ with ‘t0 c0 f0’
      ‘x’ is a rigid type variable bound by
        the instance declaration
        at Main.hs:36:10-30
      Expected type: t0 c0 f0 x1
        Actual type: x x1
    • In the second argument of ‘($)’,namely ‘undef2 x’
      In the expression: conName $ undef2 x
      In an equation for ‘gname’: gname x = conName $ undef2 x
    • Relevant bindings include
        x :: D1 m x x1 (bound at Main.hs:37:9)
        gname :: D1 m x x1 -> String (bound at Main.hs:37:3)
   |
37 |   gname x = conName $ undef2 x

所以对于我来说,为什么相同的代码在一种情况下有效(x =(来自Cc))却在另一种情况下失败,这是我一个谜。

我找到了一个完全没有conName的解决方案,但是看起来很奇怪, 低得多的水平。

instance (KnownSymbol dcn) => GDConstrName (D1 m (C1 ('MetaCons dcn p f) gg)) where
  gname x = symbolVal (undefined :: Proxy dcn)

我运行Ghc 8.4.4

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)