Haskell:如何使用haskeline并在同一程序中写入文件
我用Haskell编写了一个程序,在当前目录中以txt文件的形式构建一个吉他标签。它从用户那里获取一串和弦,然后构建适当的输出,并将其逐行写入文件 当我使用getLine时,我无法在输入上使用backspace键,因为它会在屏幕上打印一堆乱七八糟的内容 我正在尝试使用haskeline来解决这个问题,同时我注释掉了我的主要方法的大部分,这样每次更改都需要更少的编辑(我在“main”中注释掉的每个命令都与我保留的单个命令的类型相同,所以如果我能让这个简化版本正常工作,整个过程都应该正常工作)。基本上,我需要能够使用haskeline从用户那里获得输入,但是在我这样做之后,我还需要在我的“do”块中运行一些“sideeffects”命令 我是Haskell的新手,我不完全理解什么是允许的,什么是不允许的,为什么不允许。以下是我的程序的简化版本:Haskell:如何使用haskeline并在同一程序中写入文件,haskell,io,functional-programming,monads,haskeline,Haskell,Io,Functional Programming,Monads,Haskeline,我用Haskell编写了一个程序,在当前目录中以txt文件的形式构建一个吉他标签。它从用户那里获取一串和弦,然后构建适当的输出,并将其逐行写入文件 当我使用getLine时,我无法在输入上使用backspace键,因为它会在屏幕上打印一堆乱七八糟的内容 我正在尝试使用haskeline来解决这个问题,同时我注释掉了我的主要方法的大部分,这样每次更改都需要更少的编辑(我在“main”中注释掉的每个命令都与我保留的单个命令的类型相同,所以如果我能让这个简化版本正常工作,整个过程都应该正常工作)。基本
import Data.List
import System.Console.Haskeline
main = runInputT defaultSettings loop
where
loop :: InputT IO ()
loop = do
name <- getInputLine "Enter name of song: "
case name of
Nothing -> return ()
Just songName -> return ()
chords <- getInputLine "Enter chords to be tabified "
case chords of
Nothing -> do outputStrLn $ "No chords entered. Exiting."
Just chords -> do
writeFile "./test.txt" "did it work?"
return ()
Input是MonadTrans so的一个实例
Just chords -> lift $ do
编辑:
他在。(帽子提示:)由于
input IO
是MonadIO
的一个实例,您可以使用
liftIO :: IO a -> InputT IO a
事实上,这是在支持IO但不支持IO的MOAND中“运行IO”的标准方法。我尝试在“writeFile”和“return()”行之前,将其添加到我的项目中,但我得到了以下错误:“变量不在范围内:lift::IO()->Input IO()”,我想这个错误可能意味着我需要导入一个库来使用“lift”,但我到处都找过了,却找不到。我发现有些库像Control.Applicative,但它使用了一种叫做“LiftA”的东西,我怀疑这是同一回事。你有什么想法吗?@BabaSvoloch:For
lift
你想从变形金刚那里得到什么;对于liftIO
来说,它以前在变压器中,但现在在base中。你可以更容易地找到这些东西。嗨@chi,非常感谢你的解释。我仍然无法从上面运行我的示例;我想我把语法搞乱了。如果不太麻烦的话,你能告诉我如何把它整合到我的程序中吗?@BabaSvoloch你需要检查你的行为类型。例如,writeFile…
返回IO()
,因此您需要使用liftIO(writeFile…
将其转换为输入IO()
。相反,getInputLine…
应该已经可以了——不需要提升。谢谢,我让它工作了!我的问题是,当我尝试使用“liftIO”时,ghci建议我指的是haskeline库中的“liftIOOp”,我认为这是相同的函数,haskeline库最近已经更新。我没有意识到liftIO不是来自haskeline库,我需要导入Control.Monad.IO.Class
liftIO :: IO a -> InputT IO a