【问题标题】:getLine x times haskellgetLine x 次 haskell
【发布时间】:2014-12-25 19:58:55
【问题描述】:

基于Hackerrank question

我的问题是如何在 stdIn 上执行 getLine t 次?

main = do
    t <- getInt
    let x = [divisorsInNumber unsafeGetInt | a <-[1..t] ]
    print x

getInt :: IO Int
getInt = fmap read getLine

unsafeGetInt :: Int
unsafeGetInt = unsafePerformIO getInt

divisorsInNumber n = length $ filter (== True) $ map (isDivisor n) (integralToListOfInts n)

【问题讨论】:

  • 另外,还有readLn,其行为类似于fmap read getLine,但更好地处理不可读的内容。

标签: haskell io stream


【解决方案1】:

只需将getLine 操作与replicateM 复制t 次:

import Control.Monad (replicateM)

getLines :: Int -> IO [String]
getLines t = replicateM t getLine

因此getInts,即getInt t 次,可以表示为:

getInts :: Int -> IO [Int]
getInts = fmap read <$> getLines

使用getInts 重写的完整代码可能是:

import Control.Applicative ((<$>))
import Control.Monad (replicateM)


getLines :: Int -> IO [String]
getLines n = replicateM n getLine

getInts :: Int -> IO [Int]
getInts n = fmap read <$> getLines n

getInt :: IO Int
getInt = fmap read getLine

divisorsInNumber :: Int -> Int
divisorsInNumber n = length $ filter (isDivisor n) (integralToListOfInts n)

main :: IO ()
main = do
    t <- getInt
    nums <- getInts t
    let x = [divisorsInNumber num | num <- nums]
    print x

【讨论】:

  • 或者getInts = getLines &gt;&gt;= return . fmap read,如果你不想从Control.Applicative导入&lt;$&gt;
  • 是的,你可以这样写。
  • @Rufflewind:&lt;$&gt; 是国际海事组织的标准,足以批准在任何运行良好的地方使用它。比起f `fmap` x,我肯定更喜欢它。
  • @leftaroundabout 我同意你的观点,但这是主观的。任何建议的解决方案都可以。
  • @AndrewC 确实,我试图不对原来的例子做太多改动。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-09-15
  • 2016-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多