複数行入力
簡単な行編集可能
REPLを構成しやすいようにLazy I/O
code:InputLines.hs
-- # InputLines.hs
-- ## 言語拡張とmodule宣言
{-# LANGUAGE GHC2021 #-}
{-# LANGUAGE ImplicitParams #-}
{-# LANGUAGE ImportQualifiedPost #-}
{-# LANGUAGE LexicalNegation #-}
{-# LANGUAGE LambdaCase, MultiWayIf #-}
{-# LANGUAGE NPlusKPatterns #-}
{-# LANGUAGE DataKinds, PolyKinds, NoStarIsType, TypeFamilyDependencies #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE OverloadedRecordDot, NoFieldSelectors, DuplicateRecordFields #-}
module InputLines
( inputLines
, ginputLines
) where
import Data.Bool
import Data.Char
import Data.List
import System.Console.Haskeline
import System.IO.Unsafe
inputLines :: String
-> String
-> IO String
inputLines prompt quit = ginputLines prompt quit '\n'
inputLines :: String
-> String
ginputLines :: String -- ^ prompt
-> String -- ^ quit comand
-> Char -- ^ terminator
-> IO String
ginputLines p q t = loop id where
loop :: (String -> String) -> IO String
loop acc = unsafeInterleaveIO $ do
{ minput <- runInputT defaultSettings (getInputLine p)
; case minput of
Nothing -> return []
Just input
| input == q -> return []
| otherwise -> case break (t ==) input' of
(_,[]) -> loop (acc' . (input' ++))
(str,_) -> (acc' str :) <$> loop id
_ -> error "invalid input"
where
input' = trim input
acc' = bool (acc . (' ' :)) id (acc "" == "")
}
trim :: String -> String
trim = dropWhileEnd isSpace . dropWhile isSpace