interact 関数

interact ってどういう関数なのか調べてみた。
base-4.2.0.1:Prelude

-- | The 'interact' function takes a function of type @String->String@
-- as its argument.  The entire input from the standard input device is
-- passed to this function as its argument, and the resulting string is
-- output on the standard output device.

interact        ::  (String -> String) -> IO ()
interact f      =   do s <- getContents
                       putStr (f s)

getContents が標準入力の文字列を返す関数。

$ echo "Hello,world" | ghc -e 'getContents >>= putStr'
Hello,world

標準入力の文字列に関数を適用して返す。引数にとれる関数は型が(String->String)なので文字列を入力して文字列を返す関数。

$ echo -n "Hello" |ghc -e 'interact (\s->s++",world!\n")'
Hello,world!

同じ結果。

$ echo -n "Hello" | ghc -e 'getContents >>= (\s-> putStr (s++",world!\n"))'
Hello,world!

同じ結果。

$ echo -n "Hello" | ghc -e 'getContents >>= (\s-> return (s++",world!\n")) >>= putStr'
Hello,world!
  • runghc interact.hs < interact.hs
import Data.Char (toUpper)

main = interact' (map toUpper)

interact'   ::  (String -> String) -> IO ()
interact' f = getContents >>= return.f >>= putStr

{-
$ runghc interact.hs < interact.hs
IMPORT DATA.CHAR (TOUPPER)

MAIN = INTERACT' (MAP TOUPPER)

INTERACT'   ::  (STRING -> STRING) -> IO ()
INTERACT' F = GETCONTENTS >>= RETURN.F >>= PUTSTR

$ runghc interact.hs
Hello,world!  -- 文末で改行入力
HELLO,WORLD!  -- 大文字に変換された出力
Learn You a Haskell for Great Good!
LEARN YOU A HASKELL FOR GREAT GOOD!
-- CTL + D 入力で終了
-}
-- ■数当てゲーム in Haskell
-- http://d.hatena.ne.jp/tanakh/20040706#p1
module Main(main) where
import Random

main = randomRIO (1,100) >>= interact.doFunc

doFunc :: Int -> String -> String
doFunc ans = unlines.(game ans).(map read).words

game :: Int -> [Int] -> [String]
game ans ls = "Please Input Number. (1-100)":gen ls 
 where
  gen (x:xs) | x == ans = ["Collect Answer!"]
             | x  > ans = "Answer is smaller.":gen xs
             | x  < ans = "Answer is bigger." :gen xs
{-
Please Input Number. (1-100)
50
Answer is smaller.
25
Answer is smaller.
12
Answer is bigger.
18
Answer is bigger.
22
Answer is smaller.
20
Collect Answer!
-}