将单个击键读取到一个特定键的最简洁方法是什么?

问题描述 投票:0回答:1

我编写了下面的简单程序,确信它会吸收我击中的所有击键,并且当我击中 q 时,它会将之前的键打印为单个字符串。

import System.IO
main = do
  hSetBuffering stdin NoBuffering
  hSetEcho stdin False
  x <- takeWhile (/= 'q') <$> sequence (repeat getChar)
  print x

但事实并非如此。

这并不是说按键没有被读取,因为当我将最长的行更改为

时很明显
  x <- takeWhile (/= 'q') <$> sequence (repeat (getChar >>= \c -> print c >> return c))

当我输入字符时,它会一一打印出来;但 q 不会导致循环退出。

我的理解是,

sequence
并不懒惰,因为它会在
getChar
有机会开始其工作之前尝试运行无限的
takeWhile
操作列表。

如果是这样的话,我还有什么其他选择?

如果上面的代码片段的意图很明确,我可以补充一点,在实际应用程序中

getChar
将与
do
es
c <- getChar
的函数交换,然后对其进行处理。

haskell functional-programming io-monad
1个回答
0
投票

您可以考虑为此目的采取一些辅助措施:

getInput :: Char -> IO Char
getInput previous = do
  c <- getChar
  if c == 'q' then return previous else getInput c

这将使您能够获得

x
喜欢

x <- getInput ' '

或使用其他适当的默认值代替

' '

如果您确实想要单行代码,您始终可以使用

fix
将任何递归操作转换为 lambda 表达式。

首先,然后

import Data.Function

然后

x <-
  (fix $ \rec previous -> getChar >>= \c -> if c == 'q' then return previous else rec c) ' '
© www.soinside.com 2019 - 2024. All rights reserved.