Haskell 当类型是自由变量时,实例内类型签名中的类型类约束
当类型是Haskell中的自由变量时,如何在实例内的类型签名中添加类型类约束。例如:Haskell 当类型是自由变量时,实例内类型签名中的类型类约束,haskell,Haskell,当类型是Haskell中的自由变量时,如何在实例内的类型签名中添加类型类约束。例如: {-# LANGUAGE InstanceSigs #-} class Pair a where pair :: a -> b -> (a, b) instance Pair Int where pair :: (Show a) => a -> b -> (a, b) pair a b = (a, b) “a”是一个绑定类型变量,而: {-# LANG
{-# LANGUAGE InstanceSigs #-}
class Pair a where
pair :: a -> b -> (a, b)
instance Pair Int where
pair :: (Show a) => a -> b -> (a, b)
pair a b = (a, b)
“a”是一个绑定类型变量,而:
{-# LANGUAGE InstanceSigs #-}
class Pair a where
pair :: a -> b -> (a, b)
instance Pair Int where
pair :: (Show b) => a -> b -> (a, b)
pair a b = (a, b)
给出此错误:
source_file.hs:8:13:
No instance for (Show b)
Possible fix:
add (Show b) to the context of
the type signature for pair :: Int -> b -> (Int, b)
When checking that: forall a b. Show b => a -> b -> (a, b)
is more polymorphic than: forall b. Int -> b -> (Int, b)
When checking that instance signature for ‘pair’
is more general than its signature in the class
Instance sig: forall a b. Show b => a -> b -> (a, b)
Class sig: forall b. Int -> b -> (Int, b)
In the instance declaration for ‘Pair Int’
你不能
对的类型
对于所有a b都是。对a=>a->b->(a,b)
其中a=Int
,专门用于所有b的。Int->b->(Int,b)
在第一个示例中,您对所有AB的类型声明。显示a=>a->b->(a,b)
专门用于所有b的。Show Int=>Int->b->(Int,b)
,然后进一步减少到所有b的。Int->b->(Int,b)
。(Show约束被删除,因为它是多余的;您正在“约束”一个具体的类型,这是没有意义的。)这是正确的类型
在第二个示例中,您试图定义一个实例,其中
pair
的类型为forall b。Show b=>Int->b->(Int,b)
,这不起作用,因为这是另一种类型。在概念直观的层面上,类对是对消费者的承诺。它说“有一个函数对
,它将适用于这种类型的a
和任何其他类型的b
”。任何看到该类的人都可以使用任何类型的函数b
但您的实例试图说“我将实现此函数pair
,但仅适用于具有Show
实例的b
s”。好吧,这不是类的完整实现:类承诺为任何b
工作,但实例只对某些b
工作。我认为这是不可能的。您基本上是在尝试更改show函数的类型签名。在第一个示例中,a上的Show约束用作实例的约束,在第二个示例中,pairs类型被更改为Show b=>a->b->(a,b)
在第一种情况下,它统一了类型(Show x)=>x->b->(x,b)
和Int->b->(Int,b)
,它们在x~Int
时统一。在这种情况下,Show x
约束是完全冗余的,这就是为什么它被允许存在的原因——当类型被简化时,它会被删除。您没有在任何意义上“添加”任何约束。在第二种情况下,类型showb=>x->b->(x,b)
和Int->b->(Int,b)
根本不统一;像以前一样设置x~Int
仍然会留下不匹配的Show b
约束(这正是编译器告诉您的)。我在这里无意中寻找将约束添加到实例声明中的语法,就像这样instance SomeOtherClass a=>classbeingimplementa where