2009-11-21 25 views
0

我总是碰到一个错误,但无法理解如何使它正确。这给了我这个错误的代码示例:Haskell类的错误我一直都在跌倒,无法理解

class Someclass a where 
    somefunc :: (Num b) => b -> a -> a 

data Sometype = Somecons Int 

instance Someclass Sometype where 
    somefunc x (Somecons y) = Somecons (x+y) 

的错误信息是:

无法比拟预期的“B”型反推断类型“诠释”
“B”是(')'的第二个参数,即'y'
在'Somecons'的第一个参数中,'somefunc'的类型签名位于error.hs:3:21
'即'(x + y)'
在expr ession:Somecons

据我所知,错误消息试图告诉我,我使用了一个类型为Int的名称,他期望类型为(Num b)=> b。我无法理解的是Int符合(Num b)=> b。编译器不应该明白我告诉他什么(对于这个具体的例子,b应该是一个整数?我怎样才能使这个合适?

coment: 当然在这个特定的例子中,我可以做一些事情类型签名:

somefunc :: a -> a-> a 

但supose我想是这样的:。

data Newtype = Newcons (Int, Int) 

instance Someclass Newtype where 
    somefunc x (Newtype (y,z)) = Newtype (y+x, z) 

事情是这样的,当我试图做一些事情在Haskell反复发生

+0

呵呵......我想你的意思是'data ...'而不是'Data ...' – 2009-11-21 21:16:07

+0

是的,当然。感谢您的更正。 – 2009-11-21 21:45:31

回答

8

那么,您可以使用universal quantification考虑泛型符号时更清楚一点。因此

somefunc :: (Num b) => b -> a -> a 

意味着什么,但

somefunc :: forall a b . Num b => b -> a -> a 

这意味着你的类函数必须为任何数字b定义。

代码

Data Sometype = Somecons Int 

instance Someclass Sometype where 
    somefunc x (Somecons y) = Somecons (x+y) 

力量b一个具体类型 - Int,不与要求符合的任何数值类型的工作。

您可能希望有这样的事情

class Num b => SomeClass a b where 
    somefunc :: b -> a -> a 

instance Someclass Somecons Int where 
    -- ... 
5

这个问题可以在+运营商的签名中可以看出:

(+) :: Num a => a -> a -> a 

正因为如此,当你在somefunc使用+Int,它令b是一个Int,因此somefunc变为:

somefunc :: Int -> Sometype -> Sometype 

要实现Someclass类,somefunc预计将有此签名:

somefunc :: Num b => b -> Sometype -> Sometype 

也就是说,它应该适用于任何类型的实例Num。您的功能只有Int s一起使用。

+1

不会变成':: Int - > Sometype - > Sometype'? – yairchu 2009-11-22 08:20:57

+0

@yairchu,是的,就是这样,谢谢你的纠正。 – 2009-11-23 04:20:17

3

您不能混用类型,(+) :: a → a → a

let x = 1.2::Double; y=2::Int in x + y 

这已经失败。

Num是太一般了,如果你指定x::Double你能得到它的一个明确的 '类型转换' 工作(fromIntegral

instance Someclass Sometype where 
    somefunc x (Somecons y) = Somecons (x + (fromIntegral y)) 

我想你想是这样的

instance Someclass Sometype where 

    somefunc :: Int → Sometype → Int 
    somefunc x (Somecons y) = Somecons (x + y) 

顺便说一句,你需要键入数据,而不是数据:-)

+0

箭头和好的一切,但在哈斯克尔没有这样的事情。它是' - >'。 – 2009-11-21 21:38:56

+2

我知道,但在haskell文献中使用印刷符号是很常见的做法。一些haskell编辑甚至以我展示的方式展示这些符号。 – 2009-11-21 21:48:07

+0

我明白了。我更喜欢' - >',因为它是可复制的(不是我认为任何人都会复制粘贴这种人为的示例代码)。 – 2009-11-21 21:52:29

1

继续达里奥的电子xample,你似乎在问什么是:

class Someclass a where 
    somefunc :: exists b . (Num b) => b -> a -> a 

也就是说,而不是“你选择一个类型,我的功能将工作”的承诺,"forall b . Num b => b"意味着,你想要的“我会挑类型,所以我的函数将工作“承诺"exists b . (Num b) => b",其中Sr.费尔南德斯提到。 更重要的是,你没有显示你的约束(Num b) => b如何帮助你的情况。

真正interestingsituation是:你应该如何处理类以下类型:

data BMephType i o = BMT (i -> (o, BMephType i o)) 
instance Someclass (BMephType (Complex Double -> String) String) where 

最有可能的,你的解决方案将涉及Complex Double。某处。如果它只有涉及Complex Double,并没有其他Num类型,那么你正在寻找一种存在型,而不是一个普遍的。