当类型是Haskell中的自由变量时,如何在实例内的类型签名中添加类型类约束。例如:
DoIt
有效,' a'是一个绑定类型变量,而:
{-# 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)
给出了这个错误:
{-# 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)
答案 0 :(得分:4)
在概念直观层面,class Pair
是对消费者的承诺。它说“有这个函数pair
,它适用于此类型a
和任何其他类型b
”。任何看过该类的人都可以使用任何类型b
的函数。
但是您的实例试图说“我将实现此功能pair
,但仅适用于具有b
实例”的Show
。好吧,这不是一个完整的类实现:该类承诺适用于任何b
,但该实例仅适用于某些 b
。
答案 1 :(得分:3)
你不能。
pair
的类型为forall a b. Pair a => a -> b -> (a, b)
。
a = Int
的位置,这适用于forall b. Int -> b -> (Int, b)
。
在第一个示例中,您的类型声明forall a b. Show a => a -> b -> (a, b)
专门针对forall b. Show Int => Int -> b -> (Int, b)
,然后进一步缩减为forall b. Int -> b -> (Int, b)
。 (Show
约束只是被删除,因为它是多余的;你是"约束"具体类型,这是没有意义的。)这是正确的类型。
在第二个示例中,您尝试定义一个pair
类型为forall b. Show b => Int -> b -> (Int, b)
的实例,但由于该类型不同,因此无效。<\ n / p>