2013-09-30 128 views
0

我无法弄清楚,代码:Haskell的类型类错误

smallSum :: (Ord a, Integral a) => a -> a 
smallSum n 
    | n < 0 = 0 
    | (n < 20) = n + smallSum (n - 1) 
    | otherwise = error "Number needs to be in 1..10" 

fastSumOfSeriesLength :: (Ord a, Integral a) => a -> a 
fastSumOfSeriesLength x 
    | x < 10 = smallSum x 
    | x >= 10 = sum (take (rest - 1) [dif !! (firstDigit - 1), dif !! (firstDigit - 1) + 100..]) + smallList !! (firstDigit - 1) 
    where 
     smallList = [smallSum x | x <- [1..10]] 
     largeList = [smallSum x | x <- [11..20]] 
     dif = [l - s | l <- largeList, s <- smallList] 
     firstDigit = x `mod` 10 
     rest = x `div` 10 

错误:

ghci> :r 
[1 of 1] Compiling Main    (learn.hs, interpreted) 

learn.hs:194:32: 
    Could not deduce (a ~ Int) 
    from the context (Ord a, Integral a) 
     bound by the type signature for 
       fastSumOfSeriesLength :: (Ord a, Integral a) => a -> a 
     at learn.hs:191:26-54 
     `a' is a rigid type variable bound by 
      the type signature for 
      fastSumOfSeriesLength :: (Ord a, Integral a) => a -> a 
      at learn.hs:191:26 
    In the first argument of `(-)', namely `rest' 
    In the first argument of `take', namely `(rest - 1)' 
    In the first argument of `sum', namely 
     `(take 
      (rest - 1) 
      [dif !! (firstDigit - 1), dif !! (firstDigit - 1) + 100 .. ])' 
Failed, modules loaded: none. 

林找人指出什么是错,什么它看起来轻的工作和我需要谷歌了解更多关于这个错误的信息。

+0

快速提示:您可以删除函数的类型声明,然后将其加载到GHCi中。用':t expr'命令可以询问函数的类型。 –

回答

2

退房类型的(!!)take

*Main> :t (!!) 
(!!) :: [a] -> Int -> a 
*Main> :t take 
take :: Int -> [a] -> [a] 

既然你与同类型x在表达式中使用这些,这意味着x必须是Int - 但是你宣布这个功能应该工作以任何种类(整数)编号。 (如果您慢慢阅读错误,希望您能看到它这样说)。最简单的解决方法是导入Data.List并使用genericIndexgenericTake来代替。

+0

我宁愿说最简单的修复方法是删除类型声明或 使其成为Int - > Int,但这取决于他是否需要多态。 – MdxBhmt

+1

@MdxBhmt可能删除整个文件是最简单的。但是我的“简单”标准比我的“简单”标准要少得多。 =) –