Haskell:没有通过 IO [FilePath] 得到这个

发布于 2024-11-07 07:10:36 字数 1196 浏览 3 评论 0原文

通过 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

爱已欠费 2024-11-14 07:10:36

要获取 IO 操作的结果(即运行该操作),您可以将 IO 计算的结果绑定到一个变量:

假设:

getRecursiveContents :: FilePath -> IO String

然后您可以只打印结果:

main = do str <- getRecursiveContents "/home/xyz/myDir"
          print str

显然这只是一个例子,但是当函数实际上只有两行时,人们通常不会使用 do 表示法,并避免显式命名 str 的中间变量:

main = getRecursiveContents "/home/xyz/myDir" >>= print

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:

getRecursiveContents :: FilePath -> IO String

Then you can just print the result:

main = do str <- getRecursiveContents "/home/xyz/myDir"
          print str

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 of str:

main = getRecursiveContents "/home/xyz/myDir" >>= print
梦初启 2024-11-14 07:10:36

在 do 符号中使用 <- 来访问 [FilePath]。然后,您可以使用任何列表函数来操作它,只要您最终执行一些 IO 操作即可。

main = do putStrLn "this"
          contents <- getRecursiveContents "/home/xyz/myDir"
          print contents

或者,您可以使用 >>= 将一个 IO 操作的输出提供给另一个操作。都是一样的,只是写法不同而已。

main = do putStrLn "this"
          getRecursiveContents "/home/xyz/myDir" >>= print

的 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 some IO action.

main = do putStrLn "this"
          contents <- getRecursiveContents "/home/xyz/myDir"
          print contents

Alternatively, you can use >>= to feed the output of one IO action into another. It's the same thing, just written differently.

main = do putStrLn "this"
          getRecursiveContents "/home/xyz/myDir" >>= print

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.

離人涙 2024-11-14 07:10:36

您可以绑定 do 块中的值。这也是您可以应用纯函数(如 show、tail 等)的地方:

main = do putStrLn "this"
          x <- getRecursiveContents "/home/xyz/myDir"
          putStrLn (show x)

如果 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):

main = do putStrLn "this"
          x <- getRecursiveContents "/home/xyz/myDir"
          putStrLn (show x)

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文