我正在尝试定义一个函数,它将连接两个(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 ...
我做错了什么?
答案 0 :(得分:8)
Char
不是类型类,它是一种类型:
tupleCat :: (Integral a) => (a, Char) -> (a, Char) -> (a, [Char])
tupleCat (x1, y1) (x2, y2) =(x1 + x2, [y1] ++ [y2])
如果你真的想要Int
而不是Integral
,那么它们也是类型:
tupleCat :: (Int, Char) -> (Int, Char) -> (Int, [Char])
tupleCat (x1, y1) (x2, y2) =(x1+ x2, [y1] ++ [y2])
此外,您可以考虑将其设置为新类型并实现Monoid类型类(如注释中所示)。一种可能性是
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
(例如列表)中连接Foldable
s。当然我不知道你的意图,所以这只是一个有根据的猜测。
答案 1 :(得分:2)
到目前为止各方都有好处,但我认为值得指出你的功能代码还可以!但是,你确实弄乱了类型签名。它不是与你的函数不匹配,而是Char
是一个具体的类型,而不是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
,并将其替换为。{/ p>
PS - 上面的Monoid
想法是一个好主意,允许更多的高阶用法。但是不要担心,如果它让你感到困惑,那几个月前就会把我抛到一个非常糟糕的循环中。