我在做作业时遇到问题,必须写一个行为类似于wc
的程序。
我当前的方法如下:
import qualified Data.ByteString as BS
import qualified Data.ByteString.UTF8 as UTF8
numBytesUtf8 :: String -> Int
numBytesUtf8 = BS.length . UTF8.fromString
help = "Wrong number or wrong arguments provided.\n\
\Possible arguments are: [l, w, c, b, ll]\n\n\
\options:\n\
\ -l -> Return line count\n\
\ -w -> Return word count\n\
\ -c -> Return character count\n\
\ -b -> Return byte count\n\
\ -ll -> Return character count of the longest line"
getLongestLine l r
| r == [] = return l
| length next > length l = getLongestLine next rest
| otherwise = getLongestLine l rest
where
next = head r
rest = tail r
getLongestLineLength :: [Char] -> a -> Int
getLongestLineLength f = length . words . getLongestLine h t
where
l = lines f
h = head l
t = tail l
handleArgs :: [[Char]] -> [Char] -> IO ()
handleArgs args f
| head args == "-l" = print . length . lines $ f
| head args == "-w" = print . length . words $ f
| head args == "-c" = print . length $ f
| head args == "-b" = print . numBytesUtf8 $ f
| head args == "-ll" = print ( getLongestLineLength f )
| otherwise = putStrLn help
但是目前我遇到以下错误:
• No instance for (Show (a0 -> Int)) arising from a use of ‘print’
(maybe you haven't applied a function to enough arguments?)
• In the expression: print (getLongestLineLength f)
In an equation for ‘handleArgs’:
handleArgs args f
| head args == "-l" = print . length . lines $ f
| head args == "-w" = print . length . words $ f
| head args == "-c" = print . length $ f
| head args == "-b" = print . numBytesUtf8 $ f
| head args == "-ll" = print (getLongestLineLength f)
| otherwise = putStrLn help
|
43 | | head args == "-ll" = print ( getLongestLineLength f )
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
我对这门语言还是陌生的,直到现在为止我都感到惊讶。但是我不知道如何处理a -> Int
,也不知道如何打印它。
使用任何帮助和其他提示:)
答案 0 :(得分:8)
getLongestLine l r
| r == [] = return l
....
return
此处将l
注入到任何monad中,从而使getLongestLine
的类型具有以下形式
Monad m => something -> something -> m (something)
现在,这是一个事件:您可能不打算这样做。不幸的是,由于您也没有告诉GHC getLongestLine
的意图是什么,因此GHC推断了上面的意外类型并继续进行下去,从而在程序后面引起了问题。在getLongestLine
上输入类型签名后,您在这里会遇到类型错误。
您真不幸,因为错误的return
可能会导致类型错误,但在这种情况下并没有。
实际上,由于您使用合成,后来在monad上被选择为(->) a
length . words . getLongestLine h t
这会导致类型
getLongestLineLength :: [Char] -> a -> Int
有一个多余的a
自变量,并使getLongestLineLength
接受两个而不是一个参数(第二个参数传递给getLongestLine
,并在那里忽略)。
当您最终仅通过一个论点时,GHC最终会抱怨。
做什么:
return
。使用l
代替return l
。您的代码中还有其他几个问题,您可能需要进行一些重大更改。我建议您用words
早些时候将字符串分割成单词,然后将结果[String]
传递给程序的其余部分。不用计算最长的线,而是先计算长度,而是先计算长度,然后取最大值。
longestWordLength :: String -> Int
longestWordLength = maximum . map length . words
与您的问题没有密切关系,但有一般建议:
head
,tail
,l==[]
。尽可能使用模式匹配而不是防护。-Wall
打开警告并解决它们。这本可以向getLongestLine
报告缺少类型的标志,从而引起误解。