Haskell元组连接函数定义问题

Haskell元组连接函数定义问题,haskell,types,Haskell,Types,我试图定义一个函数,将两个(Int,Char)元组串联起来,如下所示: tupleCat :: (Integral a, Char b )=> (a, b) -> (a, b) -> (a, [Char]) tupleCat (x1, y1) (x2, y2) =(x1+ x2, [y1] ++ [y2]) 但是,我收到以下错误消息: Type constructor `Char' used as a class ... 我做错了什么?Char不是类型类,它是一种类型:

我试图定义一个函数,将两个
(Int,Char)
元组串联起来,如下所示:

tupleCat :: (Integral a, Char b )=> (a, b) ->  (a, b) -> (a, [Char])
tupleCat (x1, y1) (x2, y2) =(x1+ x2, [y1] ++ [y2])
但是,我收到以下错误消息:

Type constructor `Char' used as a class ...

我做错了什么?

Char
不是类型类,它是一种类型:

tupleCat :: (Integral a) => (a, Char) ->  (a, Char) -> (a, [Char])
tupleCat (x1, y1) (x2, y2) =(x1 + x2, [y1] ++ [y2])
如果你真的想要
Int
s而不是
Integral
,它们也是类型:

tupleCat :: (Int, Char) ->  (Int, Char) -> (Int, [Char])
tupleCat (x1, y1) (x2, y2) =(x1+ x2, [y1] ++ [y2])

进一步,您可以考虑使这一新类型和实现幺半群类型类(如注释中所建议的)。一种可能是

newtype Cat = Cat (Int, String)

instance Monoid Cat where
  mempty = Cat (0, [])
  mappend (Cat (i1,s1)) (Cat (i2,s2)) = Cat (i1 + i2, s1 ++ s2)

有了这个定义,
tupleCat
就变成了
mappend
。然后,您可以将每个可折叠的
中的
Cat
连接起来(例如列表)。当然,我不知道你的意图,所以这只是一个有根据的猜测。

到目前为止,所有的观点都很好,但我认为值得指出的是,你的函数代码是正确的!但是,您确实弄乱了类型签名。与其说它与您的函数不匹配,还不如说它是一种具体的类型,而不是像
Integral
Ord
Show
等那样的类型类

其他人共享了匹配的类型签名,我想帮助您实现这一点。通常,好的(至少)第一步是让Haskell为您确定类型

Prelude> let tupleCat (x1, y1) (x2, y2) =(x1+ x2, [y1] ++ [y2])
Prelude> :t tupleCat
tupleCat :: (Num t) => (t, t1) -> (t, t1) -> (t, [t1])
这比您想要的更一般一些,但是将
Num
替换为
Integral
,将
t1
替换为
Char
,并将您的


PS-上面的
幺半群
思想是一个伟大的思想,允许许多更高阶的使用。但是不要担心,如果它让您感到困惑,几个月前它会让我陷入一个非常糟糕的循环。

有趣的是,错误消息调用了
Char
类型构造函数,而不是…
Char
是一个不带参数的类型构造函数。请不要混淆类型构造函数(例如,
可能
)和值构造函数(例如,
只是
可能
)。@dave4420-啊,我没有混淆类型构造函数和值构造函数,但我觉得“类型构造函数”至少有一个类型参数。但我从Haskell 98的报告中看到,情况并不一定如此。。。我想我是在考虑类型函数。多亏了幺半群技巧,我才刚刚接触Haskell来使用这些东西:)我们可以定义(积分a)但不能定义(字符a),这太令人困惑了。如果有人能告诉我这些基本想法,我会很高兴的。再次感谢+1对于dave4420,Char不带任何参数:)考虑将整数包装在
Sum
中,然后使用幺半群函数---请参阅包。你的
tupleCat
将是
mappend
(classes)=>(types),在“=>”@dave4420之前应该只有class,你能把你的
mappend
建议作为答案吗?谢谢大家的帮助:)jon_darkstar,谢谢这也起作用了。我没有函数式编程的背景,只是想混日子。你们的回答如此迅速和完美,真让我着迷。你让我很开心:)我只想在函数定义上像传统的一样严格way@sak-我想你有点误解了我的意思。我没有做任何事情使它工作。尝试您的原始函数定义,但不使用任何(显式)类型签名。只要
tupleCat(x1,y1)(x2,y2)=(x1+x2,[y1]+[y2])
就可以了。bc Haskell的打字系统会帮你解决这个问题(尽管结果与你预期的略有不同)