Note: This post is written by a competent Haskell. You can save it as Main.lhs and try it in your GHCi.
First a quick note: you can get rid of semicolons and curly braces in do . In addition, putStrLn is of type IO () , so you do not need return () :
interactiveConcat1 = do x <- getLine y <- getLine putStrLn $ gxy
We will work with IO , so importing Control.Applicative or Control.Monad will come in handy:
> module Main where > import Control.Applicative > -- Repeat your definition for completeness > g :: [a] -> [a] -> [a] > g = (++)
You are looking for something like this:
> interactiveConcat :: IO () > interactiveConcat = magic g getLine getLine >>= putStrLn
What type of magic needed? It returns an IO String , takes a function that returns a String and takes a regular String s, and takes two IO String s:
magic :: (String -> String -> String) -> IO String -> IO String -> IO String
We can probably generalize this type to
> magic :: (a -> b -> c) -> IO a -> IO b -> IO c
A quick hoogle search reveals that there are already two functions of almost this type: liftA2 from Control.Applicative and liftM2 from Control.Monad . They are defined for each Applicative and - in the case of liftM2 - Monad . Since IO is an instance of both, you can choose one of them:
> magic = liftA2
If you are using GHC 7.10 or later, you can also use <$> and <*> without importing and recording interactiveConcat as
interactiveConcat = g <$> getLine <*> getLine >>= putStrLn
For completeness, let's add main so that we can easily test this functionality with runhaskell Main.lhs :
> main :: IO () > main = interactiveConcat
A simple check shows that it works as intended:
$ echo "Hello \ nWorld" | runhaskell Main.lhs
HelloWorld
References