Haskell:没有通过 IO [FilePath] 得到这个
通过 ghci 中的教程等进行工作 - 到目前为止一切顺利。但我完全错过了一些东西:我的函数构建了一个 IO [FilePath]“东西”。在 ghci 中,它的结果如下:
["xml","velocity.log.1","velocity.log"]
(为简洁起见,列表被截断)
我看到该函数正在执行我想要的操作。下一步是我想自己“打印”出来。
我所做的任何事情都不允许我打印结果。我不想在 Haskell 中延续我的 Java/C#/Python 习惯 - 这样做没有意义。我相信 Haskell 有充分的理由以不同的方式做事,但我不知道如何从这个函数中获取(有限的)价值。
module Main (
main
) where
import RecursiveContents
main = do putStrLn "this"
getRecursiveContents "/home/xyz/myDir"
这有效。但是,如果我希望 main 打印 getRecursiveContents "/home/xyz/myDir"
的结果怎么办?
在 ghci 中,我只需输入/粘贴 getRecursiveContents "/home/xyz/myDir"
,内容就会喷涌而出 - 我需要做什么才能自己打印它?
如果我这样做:
在 ghci 中 let xyz = getRecursiveContents "/home/xyz/myDir"
,我能用 xyz
做的唯一事情就是输入: xyz
并查看结果。
我不能做头、尾等。我知道 IO [FilePath]
是一些特殊的东西,与数组或列表 [a]
不同 - 但是我所做的一切都无法帮助我理解如何克服这个问题。
我一定错过了一些东西 - 我在 Learn You a Haskell 或 现实世界 Haskell。我是不是 rtfm-ing 的地方不对?
任何反馈或毒打表示赞赏。
Working through tutorials etc. in ghci - so far so good. I'm so completely missing something though : my function builds an IO [FilePath]
"thing". In ghci it comes out like this:
["xml","velocity.log.1","velocity.log"]
(list truncated for brevity)
I see that the function is doing what I want. Next step is I want to "print" that out myself.
Nothing I do lets me print the result. I don't want to perpetuate my Java/C#/Python habits in Haskell - no point in that. I believe there's a good reason for Haskell doing things differently, but I can't see how to get the (limited) value out of this function.
module Main (
main
) where
import RecursiveContents
main = do putStrLn "this"
getRecursiveContents "/home/xyz/myDir"
This works. But what if I want main to print the result of getRecursiveContents "/home/xyz/myDir"
?
In ghci I can just type/paste getRecursiveContents "/home/xyz/myDir"
and the stuff spews out - what do I have to do to print it myself?
If I do :
let xyz = getRecursiveContents "/home/xyz/myDir"
in ghci, the only thing I can do with xyz
is type:xyz <enter>
and see the result.
I cannot do head, tail, etc. etc.. I know that IO [FilePath]
is something special and not a the same as array or list [a]
- but nothing I do is helping me to understand getting past this.
I must be missing something - something I can't find in Learn You a Haskell, or Real World Haskell. Am I not rtfm-ing in the right place?
Any feedback or dope-slaps appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
要获取 IO 操作的结果(即运行该操作),您可以将 IO 计算的结果绑定到一个变量:
假设:
然后您可以只打印结果:
显然这只是一个例子,但是当函数实际上只有两行时,人们通常不会使用
do
表示法,并避免显式命名str
的中间变量:To get the results of an IO action (i.e. to run the action) you bind the results of the
IO
computation to a variable:Assuming:
Then you can just print the result:
Obviously this is just an example, but when the function really is just two lines people don't usually use
do
notation and avoid explicitly naming the intermediate variable ofstr
:在 do 符号中使用
<-
来访问[FilePath]
。然后,您可以使用任何列表函数来操作它,只要您最终执行一些IO
操作即可。或者,您可以使用
>>=
将一个IO
操作的输出提供给另一个操作。都是一样的,只是写法不同而已。的 I/O 章节
它在 GHCi 中工作的原因是,当 GHCi 评估你的表达式时,它会查看类型。如果是
IO a
,它将自动运行该操作并显示结果,而在真实的程序中,您必须自己执行此操作。请参阅 GHC 用户指南。Use
<-
in the do-notation to get to the[FilePath]
. You can then manipulate it with any list functions, as long as you end up with someIO
action.Alternatively, you can use
>>=
to feed the output of oneIO
action into another. It's the same thing, just written differently.For a more thorough explanation, see the I/O chapters of
The reason why it works in GHCi, is that when GHCi has evaluated your expression, it looks at the type. If it's
IO a
, it will run the action and display the result automatically, while in a real program you have to do this yourself. See the GHC user's guide.您可以绑定 do 块中的值。这也是您可以应用纯函数(如 show、tail 等)的地方:
如果 foo 的类型为 IO a,那么您需要使用 do 和 x <- foo 之类的方法来获取值。
请参阅任何 monad 教程以获取更多信息。
You can bind values in do blocks. This is also the place where you can apply pure functions (like show, tail and so on):
If the foo is of type IO a then you need something like do and x <- foo to get the value.
Consult any monad tutorial for more info.