2012-02-08 113 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)。