parsing - 两个 Haskell 程序如何通过 stdin 和 stdout 交换整数值而不将数据视为文本?

标签 parsing haskell stdout stdin

我有兴趣学习如何使用标准输入和输出在 Haskell 程序之间有效地发送数据。假设我想将两个程序连接在一起:“P1”将数字 5 输出到 stdout,而“P2”从 stdin 中获取一个整数,加 1,然后再次将其输出到 stdout。现在,我所知道的最好的方法是将数据作为文本从 P1 输出,将该文本解析回 P2 中的整数,然后从那里继续。例如:

P1.hs:

module Main where

main = do
  print 5

P2.hs:
module Main where

main = fmap manipulateData getLine >>= print
  where
    manipulateData = (+ 1) . (read :: String -> Int)

输出:
$ (stack exec p1) | (stack exec p2)
6

如果可能,我想使用标准 i/o 发送一个整数而不将其视为文本。我假设这仍然需要某种解析才能工作,但我希望可以将数据解析为二进制并获得更快的程序。

Haskell 有没有办法让这件事变得简单明了?由于我正在从一个基本的 Haskell 数据类型 (Int) 再次转换为相同类型,并在中间通过标准 i/o,我想知道是否有一个不需要编写自定义二进制解析器的简单解决方案(我不知道该怎么做)。谁能提供这样的方法?

最佳答案

这是我最终得到的代码:

module Main where

import qualified Data.ByteString.Lazy as BS
import qualified Data.Binary as B

main :: IO ()
main = do
  dat <- BS.getContents
  print $ (B.decode dat :: Int) + 1

另一个程序使用类似的导入和输出 5 与以下行:
BS.putStr $ B.encode (5 :: Int)

生成的程序可以通过管道连接在一起,生成的程序按要求运行。

关于parsing - 两个 Haskell 程序如何通过 stdin 和 stdout 交换整数值而不将数据视为文本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59833576/

相关文章:

haskell - 为什么 `Vector.length (Vector.replicate n 0)"没有融合?

java - 如何告诉这个Java方法在某种条件下再次执行自己?

python - Subprocess.Popen 将子进程 stdout,stderr 路由到父进程

c - 解析和嵌套指针

java - 我应该如何用Java解析这个简单的文本文件?

regex - 使用正则表达式过滤器作为 aws cloudwatch 日志指标过滤器

java - 使用 JavaParser 计算类中的方法声明 + 方法调用

debugging - 帮助调试 Haskell 中大量数据的意外 takeWhile 行为

haskell - 从元组列表中获取唯一路径

Linux/珀尔 : Additional output buffers other than STDOUT and STDERR?