haskell管道串入IO

use*_*010 6 io haskell

对不起,如果这是一个常见的问题.我有这个简单的IO()功能:

greeter :: IO()
greeter = do
  putStr "What's your name? "
  name <- getLine
  putStrLn $ "Hi, " ++ name
Run Code Online (Sandbox Code Playgroud)

现在我想调用greeter并同时指定一个预先填充的参数getLine,这样我实际上不需要进行交互.我想象一个像功能的东西

IOwithinputs :: [String] -> IO() -> IO()
Run Code Online (Sandbox Code Playgroud)

那我就做

IOwithinputs ["Buddy"] greeter
Run Code Online (Sandbox Code Playgroud)

这将产生一个IO动作,不需要用户输入,看起来像:

What's your name?
Hi, Buddy
Run Code Online (Sandbox Code Playgroud)

我想这样做而不修改原始IO()功能greeter.我也不想greeter从命令行编译和管道输入.IOwithinputs在Hoogle中我没有看到任何类似的东西.(withArgs引人入胜地命名和命名,但根本不是我想要的.)有一个简单的方法吗?或者由于某种原因它是不可能的?这是Pipes的用途吗?

vio*_*ior 2

我认为按照你的要求做并不容易,但你可以做下一步:

greeter' :: IO String -> IO()
greeter' ioS = do
  putStr "What's your name? "
  name <- ioS
  putStrLn $ "Hi, " ++ name

greeter :: IO ()
greeter = greeter' getLine

ioWithInputs :: Monad m => [a] -> (m a -> m ()) -> m()
ioWithInputs s ioS = mapM_ (ioS.return) s
Run Code Online (Sandbox Code Playgroud)

并测试它:

> ioWithInputs ["Buddy","Nick"] greeter'
What's your name? Hi, Buddy
What's your name? Hi, Nick
Run Code Online (Sandbox Code Playgroud)

模拟答案更有趣:

> ioWithInputs ["Buddy","Nick"] $ greeter' . (\s -> s >>= putStrLn >> s)
What's your name? Buddy
Hi, Buddy
What's your name? Nick
Hi, Nick
Run Code Online (Sandbox Code Playgroud)