Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/58.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 为什么可以’;哈斯克尔推导出这种类型_Haskell_Algebra_Type Variables - Fatal编程技术网

Haskell 为什么可以’;哈斯克尔推导出这种类型

Haskell 为什么可以’;哈斯克尔推导出这种类型,haskell,algebra,type-variables,Haskell,Algebra,Type Variables,我一直在试图写一个程序来实现任意领域的多项式,一个数学结构。我选择Haskell作为编程语言,并使用了GADTs语言扩展。然而,我不明白为什么GHCi不能推断出a的约束 背景: -- irreducible.hs {-# LANGUAGE GADTs #-} infixl 6 .+ infixl 7 .* class Ring a where (.+) :: a -> a -> a (.*) :: a -> a -> a fneg :: a ->

我一直在试图写一个程序来实现任意领域的多项式,一个数学结构。我选择Haskell作为编程语言,并使用了
GADTs
语言扩展。然而,我不明白为什么GHCi不能推断出
a
的约束

背景:

-- irreducible.hs

{-# LANGUAGE GADTs #-}

infixl 6 .+
infixl 7 .*

class Ring a where
  (.+) :: a -> a -> a
  (.*) :: a -> a -> a
  fneg :: a -> a
  fzero :: a
  funit :: a

class (Ring a) => Field a where
  finv :: a -> a

data Polynomial a where 
  Polynomial :: (Field a) => [a] -> Char -> Polynomial a

instance (Show a) => Show (Polynomial a) where
  show (Polynomial (a0:ar) x)
    = show a0
      ++ concatMap (\(a, k) -> "+" ++ show a ++ x:'^':show k) (zip ar [0..])
  show (Polynomial [] _) = show (fzero::a)
说明:环是定义了加法和乘法的东西,加法形成一个(实际上是阿贝尔的)群,乘法形成一个幺半群。域是定义了乘法逆的环。域上的多项式由系数列表和字符表示。字符,例如
'x'
,表示该多项式与未知变量
x
有关。对于写为
多项式[]'x'
的零多项式,我希望它显示底层字段的零元素

在运行GHCi后,我得到以下信息:

irreducible.hs:59:28: error:
    • Could not deduce (Show a0) arising from a use of ‘show’
      from the context: Show a
        bound by the instance declaration at irreducible.hs:55:10-40
      or from: Field a
        bound by a pattern with constructor:
                   Polynomial :: forall a. Field a => [a] -> Char -> Polynomial a,
                 in an equation for ‘show’
        at irreducible.hs:59:9-23
      The type variable ‘a0’ is ambiguous
      These potential instances exist:
        instance (Show a, Show b) => Show (Either a b)
          -- Defined in ‘Data.Either’
        instance Show Ordering -- Defined in ‘GHC.Show’
        instance Show Integer -- Defined in ‘GHC.Show’
        ...plus 25 others
        ...plus 87 instances involving out-of-scope types
        (use -fprint-potential-instances to see them all)
    • In the expression: show (fzero :: a)
      In an equation for ‘show’:
          show (Polynomial [] _) = show (fzero :: a)
      In the instance declaration for ‘Show (Polynomial a)’
   |
59 |   show (Polynomial [] _) = show (fzero::a)
   |                            ^^^^^^^^^^^^^^^

irreducible.hs:59:34: error:
    • Could not deduce (Ring a1) arising from a use of ‘fzero’
      from the context: Show a
        bound by the instance declaration at irreducible.hs:55:10-40
      or from: Field a
        bound by a pattern with constructor:
                   Polynomial :: forall a. Field a => [a] -> Char -> Polynomial a,
                 in an equation for ‘show’
        at irreducible.hs:59:9-23
      Possible fix:
        add (Ring a1) to the context of
          an expression type signature:
            forall a1. a1
    • In the first argument of ‘show’, namely ‘(fzero :: a)’
      In the expression: show (fzero :: a)
      In an equation for ‘show’:
          show (Polynomial [] _) = show (fzero :: a)
   |
59 |   show (Polynomial [] _) = show (fzero::a)
   |            
现在,让我们关注有问题的部分:

instance (Show a) => Show (Polynomial a) where
  show (Polynomial (a0:ar) x) = show a0 ++ [...]
  show (Polynomial [] _) = show (fzero::a)
在我看来,
多项式a
保证
a
字段
的一个实例,这意味着
a
的一个实例。因此,调用
fzero::a
,就像调用
42::Int
,应该是合理的。此外,我已经编写了
Show a
作为约束,并且
多项式a
的构造函数具有
多项式[a]Char
的形状,因此它还应该知道
a0
的类型是
Show
的一个实例

显然,译员的想法不同。我在哪里犯了错误?

来自arrowd的评论:


代码很好,但需要扩展名
ScopedTypeVariables
,这使得
fzero::a中的类型变量
a
参考前面介绍的
a

常见错误,搜索
ScopedTypeVariables
@arrowd谢谢!这对我很有用。