如何在一行代码中读取Int?

时间:2017-10-26 23:37:05

标签: haskell

我刚开始学习Haskell之后第一次用python进行函数式编程。

首先,我知道我会问的是不好的做法实际上是人类已知的每种编程语言,并且我保证除了纯粹的教育之外不会用于任何严肃的目的。那说......

我最喜欢的一件事是使用一行代码编写函数的优雅,同时仍然保持代码可读(像C / C ++样式的东西,你只需将所有语句放在由分号分隔的一行上)显然,很明显)

我已经查看了问题并尝试了至少一些不同的haskell教程和文档,并且有些事情已经接近了,但我找不到能让我在一行代码中读取可用Int的东西。

为了这个问题,让我说我想要为键盘读取Int并打印“Hello World!”。那么多次(从HackerRank无耻地被盗)。

我尝试使用getLinereadLnread的内容调查了>>=而不是记谱法,只是为了坚持使用IO操作固执地给我一个每次我没有把它们放在一个单独的陈述中时出错。

我尝试过的一些事情:

main :: IO ()
main = readLn :: IO Int >>= \n -> mapM_ putStrLn $ replicate n "Hello World!"

给出:

parse error on input ‘\’

然后

main = readLn >>= \n -> read n :: Int >>= \n -> mapM_ putStrLn $ replicate n "Hello World!"

给出了同样的错误。

同样:

main = getLine >>= \n -> read n :: Int >>= \n -> mapM_ putStrLn $ replicate n "Hello World!"

我究竟不明白什么?提前致谢!

1 个答案:

答案 0 :(得分:6)

您将类型声明与表达式混合。它应该是:

main = (readLn :: IO Int) >>= \n -> mapM_ putStrLn $ replicate n "Hello World!"

你的问题是没有包围,编译器继续解析,好像它正在读取类型声明一样,因此它在\上运行并卡住了。

但是,这种类型声明是推断的(因为replicate :: Int -> a -> [a])因此是不必要的。 删除它!

main = readLn >>= \n -> mapM_ putStrLn $ replicate n "Hello World!"

一般情况下,完全避免这种情况并使用do - 符号要好得多。这种打高尔夫球'在Haskell中非常有趣,但不是制作清晰,可维护代码的方法。

import Control.Monad (replicateM_)

main = do
    n <- readLn :: IO Int                   -- Type optional here.
    replicateM_ n $ putStrLn "Hello World!" -- A more concise expression.