2011-06-12 69 views
0
--Standered Diviation 
module SD where 
diviation:: IO() 
diviation = 
    do 
     putStrLn ("Enter Students Marks") 
     marks <- getLine 
     let m = (read marks)::[Float] 
     let x = sum' m 
     let mean = (fromIntegral x)/(fromIntegral $ length) 
     let len = (read (length(m)))::Float 
     let divia = divi mean l 
     let std = map (^2) divia 
     let stdd = xx length(m-1) m 
     let final = map sqrt stdd 
     let tot = sum final 

     if(m==[]) 
       then 
       putStrLn("empty List" ++ show(tot)) 
      else do 
       putStrLn("The Standered Divation is" ++ (show(tot))) 


sum' :: (Num a) => [a] -> a 
sum' = foldl (+) 0 

avg::Float->Float->Float 
avg a b = (fromIntegral a)/(fromIntegral b) 

divi::Float->[Float]->[Float] 
divi a xs = [x-a | x <- xs] 

xx::Float->[Float]->[Float] 
xx a xs = [x/a|x<-xs] 

我找不出這個程序有什麼問題。是這樣表示haskell程序問題(類型錯誤)

ERROR file:.\SD.hs:11 - Type error in application 
*** Expression  : read (length m) 
*** Term   : length m 
*** Type   : Int 

錯誤你們可以請點我出的問題在這個方案,謝謝 *不匹配:[字符]

+4

你不能在'Int'上調用'read',這是'length'返回的結果。 'read'用於字符串。 – 2011-06-12 17:18:15

+0

你也沒有真正使用這個值'len'。所以只要刪除行'let len =(read(length(m)):: Float' – 2011-06-13 19:08:32

回答

0

功能讀取具有類型字符串 - > '一個 ;你的錯誤告訴你長度爲m的類型爲Int,而read等待一個String。您可能想使用Data.List中的genericLength:

let len = Data.List.genericLength m :: Float 
1

您的代碼中有幾件事情您可能需要查看。你有:

let stdd = xx length(m-1) m 

這將不會typecheck。我想你的意思是:

let stdd = xx (length m-1) m 

(編輯:實際上,將不檢查或者是由於對XX類型簽名(爲什麼不)?)這條線:

let mean = (fromIntegral x)/(fromIntegral $ length) 

Num除以函數

在這一行:`

let std = map (^2) divia 

是什麼divia類型,什麼是(^2)類型?

最後,在空列表甚至單例列表的情況下實際發生了什麼?

另一方面,您可能想要考慮程序的哪些部分真的需要在main之內生存。既然這樣,你

  • 打印線
  • 讀取輸入
  • 計算標準偏差
  • 打印的計算結果

爲什麼不分解出一個standardDev功能?這可能會使您的main功能更短,更清晰。編寫純函數還允許您更方便地在REPL中測試函數。當我編寫代碼時,我發現構建簡短的,明顯正確的函數非常有用,可以將它們組合起來以獲得所需的行爲,並且只在最後時刻將結果轉儲到IO monad中。