繁体   English   中英

Haskell将[IO String]加入IO String的方法

[英]Haskell way to join [IO String] into IO String

我的目标是编写Haskell函数,它从输入中读取N行并将它们连接成一个字符串。 以下是第一次尝试:

readNLines :: Int -> IO String
readNLines n = do
  let rows = replicate n getLine
  let rowsAsString = foldl ++ [] rows 
  return rowsAsString  

这里有关于foldl抱怨:

无法匹配预期类型[a]' against inferred type (a1 - > b - > a1) - > a1 - > [b] - > a1'

据我所知,行的类型是[IO String] ,是否有可能在单个IO String加入这样的列表?

除了ephemient指出的,我认为你有一个语法问题:你使用++运算符的方式使它看起来像你试图用操作数foldl[]调用++运算符。 ++运算符放在括号中以使您的意图清晰:

foldl (++) [] rows

您正在寻找的功能是sequence ,但应注意

sequence (replicate n f)

是相同的

replicateM n f

foldl (++) []相当于concat 所以你的功能是:

readNLines n = liftM concat (replicateM n getLine)

或者,如果您想保留换行符:

readNLines n = liftM unlines (replicateM n getLine)

我能想出的最短的答案是:

import Control.Applicative
import Control.Monad

readNLines :: Int -> IO String
readNLines n = concat <$> replicateM n getLine

replicate返回IO String操作列表。 为了执行这些操作,需要在IO monad中运行它们。 所以你不想加入一系列IO动作,而是按顺序运行它们并返回结果。

这就是我要做的

readNLines :: Int -> IO String
readNLines n = do
  lines <- replicateM n getLine
  return $ concat lines

或者,在应用风格:

import Control.Applicative

readNLines :: Int -> IO String
readNLines n = concat <$> replicateM n getLine

这两个都使用monadic replicate(replicateM),它按顺序计算monadic值列表,而不是简单地返回一个action列表

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM