簡體   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