2013-02-18 62 views
2

我試圖找出最新的錯誤。似乎類型有問題,但單獨使用相同的表達方式可以正常工作。類型錯誤與分數相關

下面是代碼:

a = [9, 4, 12, 0, -6, 16] :: [Int] 

qsort:: [Int] -> [Int] 
qsort [] = [] 
qsort [x] = [x] 
qsort xs = (qsort l)++(qsort r) 
    where m = (realToFrac(sum xs))/(realToFrac(length xs)) 
      l = filter (<=m) xs 
      r = filter (>m) xs 

main::IO() 
main = do 
     print (show (qsort a)) 

它拋出:

main.hs:7:36: 
    No instance for (Fractional Int) 
     arising from a use of `/' 
    Possible fix: add an instance declaration for (Fractional Int) 
    In the expression: (realToFrac (sum xs))/(realToFrac (length xs)) 
    In an equation for `m': 
     m = realToFrac (sum xs)/(realToFrac (length xs)) 
    In an equation for `qsort': 
     qsort xs 
      = (qsort l) ++ (qsort r) 
      where 
       m = realToFrac (sum xs)/(realToFrac (length xs)) 
       l = filter (<= m) xs 
       r = filter (> m) xs 

但是效果很好:

a = [9, 4, 12, 0, -6, 16] :: [Int] 
main::IO() 
main = do 
    print (show ( (realToFrac(sum a))/(realToFrac(length a)) )) 
+0

替代解決方案:刪除'realToFrac'和使用''總和XS'quot'長度xs''; ''''是'Integral'類型的劃分(向零捨去/舍入;'div'向-infinity舍入),並且由於'xs :: [Int]','sum xs'和'length xs'具有相同的鍵入('Int'),以便在沒有轉換的情況下運行。 – 2013-02-18 18:37:26

回答

6

m定義給出了一些Fractional類型。 但是,您在lr的定義中比較mInt,這使混淆編譯器。 下面將做的伎倆:

a = [9, 4, 12, 0, -6, 16] :: [Int] 

qsort:: [Int] -> [Int] 
qsort [] = [] 
qsort [x] = [x] 
qsort xs = (qsort l)++(qsort r) 
    where m = realToFrac(sum xs)/(realToFrac(length xs)) 
      l = filter ((<=m) . fromIntegral) xs 
      r = filter ((>m) . fromIntegral) xs 

main::IO() 
main = do 
     print (show (qsort a)) 
+0

非常好,謝謝:) – crimsonlander 2013-02-18 16:54:50

5

realToFrac(sum xs)/(realToFrac(length xs))的工作,但它的結果是一個小數。所以在你的代碼m是一個分數。但是,您將m與您列表中的項目進行比較,這些項目是Ints。由於只能比較相同類型的值,並且Ints不是小數,因此會導致類型錯誤。

要解決您的問題,您可以使用整數除法(div)或將列表中的整數轉換爲小數,然後再將它們與m進行比較。

+0

是的,你是對的。但那麼,爲什麼我可以做到4.5 <5沒有錯誤? – crimsonlander 2013-02-18 16:52:33

1

您可以使用x作爲您的支點。列表模式匹配「qsort(x:xs)」在這裏幫助很大。

a = [9, 4, 12, 0, -6, 16] :: [Int]                      

qsort:: [Int] -> [Int]                         
qsort [] = []                           
qsort (x:xs) = (qsort l) ++ [x] ++ (qsort r)                   
    where l = filter (<=x) xs                      
      r = filter (>x) xs                       

main::IO()                            
main = putStrLn $ show $ qsort a 

-- *Main> main                           
-- [-6,0,4,9,12,16] 

替代語法,以及:http://hpaste.org/81793

+2

您的編輯不正確@crimsonlander。快速排序通過在過濾過程完成後將每個支點元素放置在正確的位置來工作。因此[x]必須位於(qsort l)和(qsort r)(正確排序的位置)的中間 – 2013-02-18 18:47:36

+0

對不起,沒有注意到一些細節:) – crimsonlander 2013-02-18 19:00:18