Haskell交互功能 [英] Haskell interact function
问题描述
我是Haskell的新手,并且遇到 interact
函数的问题。这是我的示例程序:
main :: IO()
main = interact inputLength
inputLength :: String - >字符串
inputLength输入=显示$长度输入
编译但运行不打印输出 - 只是打印传递给它的字符串并移动到下一行。当我通过交互
另一个字符串 - > String
这样的函数:
upperCase :: String - > String
upperCase input = map toUpper input
它运行正常并以大写形式输出参数为预期 - 那么第一个函数有什么问题?
map toUpper
懒惰地行动 - 它可以在所有输入已知之前开始给出输出。找到一个字符串的长度不是这样的 - 在产生任何输出之前必须知道整个字符串。 您需要发信号通知EOF说你完成了输入(在控制台中,这是Unix / Mac系统上的Control-D,我相信它是Windows上的Control-Z),那么它会给你一个长度。或者你可以通过这样的方式找到每行的长度:
interact(unlines。map(show。length)。lines)
这在每一行中都是懒惰的,所以你知道每次输入后你都可以得到一个输出。
由于在线上行事是一种常见模式,我喜欢定义一个小帮手函数:
eachLine ::(String - > String) - > (字符串 - >字符串)
eachLine f = unlines。地图f。行
然后你可以这样做:
main = interact(eachLine inputLength)
I’m new to Haskell and have a problem with interact
function. This is my sample program:
main :: IO ()
main = interact inputLength
inputLength :: String -> String
inputLength input = show $ length input
It compiles but when running doesn’t print the output - just prints the string that is passed to it and moves to the next line. When I pass the interact
another String -> String
function like this:
upperCase :: String -> String
upperCase input = map toUpper input
it runs ok and prints the argument in uppercase as expected – so what is wrong with the first function?
interact :: String -> String
takes a string containing all the input and returns a string containing all the output. The reason you see output after pressing enter with interact (map toUpper)
is because map toUpper
acts lazily -- it can start giving output before all the input is known. Finding the length of a string is not like this -- the whole string must be known before any output can be produced.
You need to either signal an EOF to say that you are done entering input (in the console, this is Control-D on Unix/Mac systems, I believe it's Control-Z on Windows), then it will give you the length. Or you can find the length of each line by saying so:
interact (unlines . map (show . length) . lines)
This will always be lazy in each line, so you know you can get one output after each input.
Since acting on lines is such a common pattern, I like to define a little helper function:
eachLine :: (String -> String) -> (String -> String)
eachLine f = unlines . map f . lines
Then you can do:
main = interact (eachLine inputLength)
这篇关于Haskell交互功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!