Haskell:如何使用haskeline并在同一程序中写入文件

问题描述 投票:2回答:2

我在Haskell中编写了一个程序,它将吉他选项卡构建为当前目录中的txt文件。它从用户获得一串和弦,然后构建正确的输出并将其逐行写入文件。

当我使用getLine时,我无法在输入上使用退格键,因为它会在屏幕上打印出一堆乱码。

我正在尝试使用haskeline来解决这个问题,并且在此期间我注释了我的主要方法的大部分内容,以便每次更改都需要更少的编辑(我在'main'中注释的每个命令都与单个命令的类型相同我保留了,所以如果我能让这个简化版本工作,整个事情应该有效)。基本上,我需要能够使用haskeline从用户那里获得输入,但是之后我还需要在我的“do”块中运行一些“副作用”命令。

我是Haskell的新手,我不完全明白什么是允许的,也不允许的。这是我的程序的简化版本:

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 ()

我直接从Haskeline教程获得了所有这些语法。我尝试先运行它而不先进行任何更改,但它确实有效 - 所以我知道它是正确的 - 除了我编辑的最后3行,我有“do”块,我试图在“之前”调用“writeFile”返回()”。

我知道“循环”的类型必须是InputT IO()才能使用getInputLine(getLine的haskeline版本),但我不知道如何完成“副作用”,比如同时写入文件时间。

当我尝试在ghci中加载项目时,出现以下错误:

error:
-Couldn't match type 'IO' with 'InputT IO'
 Expected type: InputT IO ()
   Actual type: IO ()
- In a stmt of a 'd' block: writeFile "./test.txt" "did it work?"
  In the expression:
    do { writeFile "./test.txt" "did it work?";
         return () }
  In a case alternative:
    Just chords
      -> do { writeFile "./test.txt" "did it work?";
              return () }

Failed, modules loaded: none.
haskell io functional-programming monads haskeline
2个回答
4
投票

由于InputT IOMonadIO的一个实例,你可以通过将其提升为InputT IO动作来运行任何IO动作,

liftIO :: IO a -> InputT IO a

实际上,这是在支持IO但不是IO的moand中“运行IO”的标准方法。


4
投票

输入是Monad Trans的一个实例

Just chords -> lift $ do

编辑:

liftControl.Monad.Trans.Class。 (帽子提示:Jon Purdy

© www.soinside.com 2019 - 2024. All rights reserved.