Haskell 带IO字符串的hPutStrLn?
我有一个必须使用的函数,名为:Haskell 带IO字符串的hPutStrLn?,haskell,Haskell,我有一个必须使用的函数,名为: hPutStrLn 该函数具有以下类型: hPutStrLn::Handle->String->IO() 我想做的是,它使用一个shell命令行grep,获取输出并传输到hPutStrLn的字符串变量 例如: tryA (arrIO (\s -> hPutDocument (\h-> hPutStrLn h (readProcess "grep" ["-n",s,"camera2.owl"] "")))) 但问题是,我的readProcess有一个
hPutStrLn
该函数具有以下类型:
hPutStrLn::Handle->String->IO()
我想做的是,它使用一个shell命令行grep
,获取输出并传输到hPutStrLn
的字符串变量
例如:
tryA (arrIO (\s -> hPutDocument (\h-> hPutStrLn h (readProcess "grep" ["-n",s,"camera2.owl"] ""))))
但问题是,我的readProcess有一个IO字符串类型,如果我想使用函数hPutStrLn
,它必须是一个字符串!
我不知道怎么才能解决这个问题。。。
所以我有几个问题是:
-我可以从IO字符串中提取字符串吗?
-如果我不能,还有别的办法吗
hPutDocument功能
hPutDocument :: (Handle -> IO ()) -> IO ()
hPutDocument action
| isStdout
= do
hSetBinaryMode stdout (not textMode)
action stdout
hSetBinaryMode stdout False
| otherwise
= do
handle <- ( if textMode
then openFile
else openBinaryFile
) dst WriteMode
action handle
hClose handle
isStdout = null dst || dst == "-"
outFile = if isStdout
then "stdout"
else show dst
hPutDocument::(句柄->IO())->IO()
hPutDocument操作
|isStdout
做
hSetBinaryMode标准输出(非文本模式)
动作标准
hSetBinaryMode标准输出错误
|否则
做
handle最简单的方法是使用do
表示法。您可以定义一个要传递给hPutDocument
的辅助函数:
doGrep :: Handle -> IO ()
doGrep h =
do
str <- readProcess "grep" ["-n",s,"camera2.owl"] ""
hPutStrLn h str
tryA (arrIO (\s -> hPutDocument doGrep))
>=
具有以下类型:
(>>=) :: IO a -> (a -> IO b) -> IO b
在这种特殊情况下,a=String
和b=()
因此这里>=
获取由readProcess…
生成的IO字符串
,并将其传递给第二个参数,该参数是一个函数,它获取字符串
并生成IO()
。总体结果是第二个函数生成的IO()
符号\str->hPutStrLn h str
定义了一个匿名函数(“lambda”),该函数将str
作为参数,并生成hPutStrLn h str
的结果
上面的do
符号实际上是由编译器翻译成的(“desugared”)
在此特定实例中,您还可以将\str->hPutStrLn h str
缩短为hPutStrLn h
,还可以使用反向绑定操作符=
pSince codehPutStrLn/code有类型codeHandle->String->IO()
,hPutStrLn h
有类型String->IO()
,只要h
有类型Handle,最简单的方法是使用do
符号。您可以定义一个要传递给hPutDocument
的辅助函数:
doGrep :: Handle -> IO ()
doGrep h =
do
str <- readProcess "grep" ["-n",s,"camera2.owl"] ""
hPutStrLn h str
tryA (arrIO (\s -> hPutDocument doGrep))
>=
具有以下类型:
(>>=) :: IO a -> (a -> IO b) -> IO b
在这种特殊情况下,a=String
和b=()
因此这里>=
获取由readProcess…
生成的IO字符串
,并将其传递给第二个参数,该参数是一个函数,它获取字符串
并生成IO()
。总体结果是第二个函数生成的IO()
符号\str->hPutStrLn h str
定义了一个匿名函数(“lambda”),该函数将str
作为参数,并生成hPutStrLn h str
的结果
上面的do
符号实际上是由编译器翻译成的(“desugared”)
在此特定实例中,您还可以将\str->hPutStrLn h str
缩短为hPutStrLn h
,还可以使用反向绑定操作符=
pSince codehPutStrLn/code有类型codeHandle->String->IO()
,hPutStrLn h
有类型String->IO()
,只要h
有类型Handle,首先感谢您的回答!我必须说,我正在尝试使用HXT库制作的haskell函数。我为了我自己的目的和我自己的目标重新认识它。有一件事我不明白,就是(\s->…和(\h->…这意味着什么?第二,如果我不必使用do符号
,我没有正确理解您的第二种方法,即>=
。我已经对我的答案进行了一些扩展,以解释所使用的语法和概念,但如果您有一个问题不是关于我的答案,最好重新开始流程问题。我编辑了我的帖子,但函数丢失了。我仍然不明白当hPutDocument
需要我的hputstrn
时,我怎么能使用你的=/code>,而你告诉我这样做tryA…>=\str->hputstrn h-str
。我有点困惑,我没有仔细阅读你的问题(部分原因是代码格式不正确-任何产生水平滚动条的内容都很难阅读!)并且没有注意到hPutStrLn调用在代码中,没有在结果中使用。我现在更正了我的答案。谢谢!现在,我明白了!)首先,感谢您的回答!我必须说我正在尝试使用HXT库制作的haskell函数。我正在用我自己的目标重新转换它。有一件事我不明白,那就是(\s->…和(\h->…这是什么意思?第二,如果我不必使用do符号
,我就不理解您的第二个ap