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的打字系统会帮你解决这个问题(尽管结果与你预期的略有不同)