2012-07-31 18 views
1

当我尝试编译这段代码无法推断出等差数列出现(一个枚举)`(X - N + 1).. X”

prod [] = 1 
prod (x:xs) = x * prod xs 

ff :: (Num a) => a -> a -> a 
ff x n = prod [(x - n + 1) .. x] 

我获得以下错误:

a.hs:5:15: 
    Could not deduce (Enum a) 
    arising from the arithmetic sequence `(x - n + 1) .. x' 
    from the context (Num a) 
     bound by the type signature for ff :: Num a => a -> a -> a 
     at a.hs:5:1-32 
    Possible fix: 
     add (Enum a) to the context of 
     the type signature for ff :: Num a => a -> a -> a 
    In the first argument of `prod', namely `[(x - n + 1) .. x]' 
    In the expression: prod [(x - n + 1) .. x] 
    In an equation for `ff': ff x n = prod [(x - n + 1) .. x] 

这段代码有什么问题?当我用Double代替一切都是正确的。

+1

'Num'不是'Enum',因为你可以有'Num'类型,很难枚举,比如'Complex'。 – Landei 2012-07-31 09:58:54

+0

删除'ff'的类型签名并查看编译器推导的类型。 – augustss 2012-07-31 16:31:58

+0

@augustss如何检查编译器的推导结果? – Trismegistos 2016-09-19 10:28:40

回答

7

[i .. j]enumFromTo i j的简写。 enumFromTo是类型Enum的一部分,而不是Num的一部分(但仍需要Num才能使用+-)。

所以,你需要说a实现Enum以及实施Num

ff :: (Num a, Enum a) => a -> a -> a 
ff x n = prod [(x - n + 1) .. x] 

它与Double因为Double同时实现了这些类型类。

+0

直指点! – Trismegistos 2012-07-31 10:02:33

1

ff :: (Enum a, Num a) => a -> a -> a
ff x n = prod [(x - n + 1) .. x]

2

为了[x .. y]工作,结果类型并不需要在所有的一个实例Num(例如,['A'..'Z']作品就好了)。它需要是一个Enum实例。只需将Enum添加到类型签名即可。

它与Double一起使用,因为Double有两个实例。

相关问题