TL; DR。
foldLeft (\_ x -> putStrLn x) (pure ()) ("2":."1":.Nil)
为什么上面的代码输出
而不是
2
1
完整问题
我在做FP课程的练习
https://github.com/system-f/fp-course/blob/5e0848b4eacb3ddff65553ab5beb6447b73f61b3/src/Course/FileIO.hs#L97
对此我有两个解决方案。
printFiles ps = void . sequence $ (uncurry printFile) <$> ps
printFiles = foldLeft (\_ (fp, content) -> printFile fp content) (pure ())
第一个是正确的,可以打印为问题的要求。
>> :main "share/files.txt"
============ share/a.txt
the contents of a
============ share/b.txt
the contents of b
============ share/c.txt
the contents of c
第二次打印如下。
>> :main "share/files.txt"
============
share/c.txt
the contents of c
看起来pure ()
只收集foldLeft
的最后一个printFile fp content
。
如何使pure ()
又名IO ()
收集所有putStrLn
在foldLeft
?
2条答案
按热度按时间olmpazwi1#
您构造一个
putStrLn "1"
作为最终结果,并由此生成。注意IO a
* 不是 * 一个 * 发生过 * 的动作,或者总是会发生,你应该把它看作是动作的某种委托,所以是一个配方,你可以把合并配方和**(>>) :: Monad m => m a -> m b -> m b
**结合起来,创建一个 * 新的 * 配方,它首先运行第一个操作数,然后是正确的操作数。所以在这种情况下,我们可以用以下方法修复它:
所以最终结果将是
putStrLn "2" >> putStrLn "1"
,它是IO ()
,当调用时将首先打印"2"
,然后打印"1"
。yptwkmov2#
因为Haskell是引用透明的,所以你总是可以通过手动计算表达式来回答这样的问题,即内联函数调用和beta缩减,直到很明显发生了什么:
所以这就是你得到的:一张
"1"
的照片奥托赫,根据威廉货车昂塞姆的建议,