Haskell元组连接函数定义问题

时间:2011-06-23 07:42:55

标签: 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 ...

我做错了什么?

2 个答案:

答案 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是一个具体的类型,而不是IntegralOrdShow等类型类。

其他人分享了匹配类型签名,我想帮助你实现目标。通常一个好的(至少)第一步是让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想法是一个好主意,允许更多的高阶用法。但是不要担心,如果它让你感到困惑,那几个月前就会把我抛到一个非常糟糕的循环中。