2012-02-08 84 views
-3

請問您可以告訴我如何解決這個錯誤在我的代碼?haskell中的高階函數Error2

{--------------------- BINARY TO DECIMAL MENU ---------------} 

functionBinToDecimal:: IO() 
functionBinToDecimal= do 
    putStrLn("\n\tConvert Binary To Decimal\n") 
    putStrLn("----------------------------------------------------------\n") 
    putStrLn("\t\tEnter a binary number : ") 
    input<-getLine 
    let n=(read (reverse input))::String 
    let result = convertionFrom binaryToDec n 
    putStrLn(show result) 

{----------------BINARY TO DECIMAL---------------------} 

binaryToDec :: String -> Int 
binaryToDec = foldr (\x s -> s * 2 + x) 0 . reverse . map charToInt 
    where charToInt x = if x == '0' then 0 else 1 

conversionFrom :: (String -> Int) -> String -> Int 
conversionFrom _ [] = 0 
conversionFrom f (x:xs) = f x ++ conversionFrom f xs 

錯誤

test.hs:28:27: 
    Couldn't match expected type `Int' with actual type `[a0]' 
    In the expression: f x ++ conversionFrom f xs 
    In an equation for `conversionFrom': 
     conversionFrom f (x : xs) = f x ++ conversionFrom f xs 
+0

旁註:它拼寫爲「轉換」,而不是「轉換」。 – dflemstr 2012-02-08 06:39:58

+3

您**瞭解**錯誤信息的含義? [我昨天解釋](http://stackoverflow.com/a/9177409/86622)如何閱讀這種錯誤信息。 – dave4420 2012-02-08 07:59:12

回答

0

您需要添加的f x結果的遞歸調用。您現在試圖預先考慮結果。

嘗試:

convenrtionFrom f (x : xs) = f x + convertionFrom f xs 
1
convertionFrom :: (String -> Int) -> String -> Int 

說,你的第一個參數是採取一個字符串的函數...

convertionFrom f (x:xs) = f x ++ convertionFrom f xs 

是模式匹配,以第二個參數(字符串)並將x綁定到字符串的頭部(一個字符)。

所以f需要一個字符串,但你傳遞一個字符。

0

問題是,++是列表連接,而不是加法 - 它期望並返回列表,但是你傳遞int並期望返回int。這就是說,convertionFrom有什麼意義? binaryToDec n應該將字符串形式的二進制數轉換爲無問題的int形式。通過binaryToDecconvertionFrom不可能是正確的,因爲在binaryToDec上調用convertionFrom而字符串將字符傳遞到binaryToDec,這將導致另一個類型錯誤,如Mikel所述。

1

那麼你根本不需要conversionFrom函數。計算十進制形式二進制的工作是binaryToDec,並單獨使用它的作品。

+0

oki但我需要一個HOF(高階函數) – JJ23 2012-02-08 07:16:39

+1

您認爲foldr的第一個參數是什麼?它是一個匿名函數,您可以將它作爲函數的參數。所以你有你的HOF。 – Friedrich 2012-02-08 07:43:47

2

附加提示:您不需要反轉,只需使用foldl而不是foldr即可。

binaryToDec = foldl (\n c -> 2*n + if c=='1' then 1 else 0) 0 
0

附加額外提示:有已經與任意進制轉換StringInt(實際上,任何Num實例)的功能,這就是所謂的Numeric.readInt。這是一個HOF,需要兩個函數參數,所以它比foldl好!

您可以使用Char.digitToInt將數字Char轉換爲Int(而不是charToInt)。