作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我无法理解这个 Haskell 表达式的工作原理:
import Control.Monad
import System.IO
(forM_ [stdout, stderr] . flip hPutStrLn) "hello world"
. flip hPutStrLn
部分在做什么?类型签名看起来很复杂:
ghci> :type flip
flip :: (a -> b -> c) -> b -> a -> c
ghci> :type (.)
(.) :: (b -> c) -> (a -> b) -> a -> c
ghci> :type (. flip)
(. flip) :: ((b -> a -> c1) -> c) -> (a -> b -> c1) -> c
ghci> :type (. flip hPutStrLn)
(. flip hPutStrLn) :: ((Handle -> IO ()) -> c) -> String -> c
(.)
的左右操作数是什么?运算符作为表达式被评估?
(forM_ [stdout, stderr] . flip hPutStrLn) :: String -> IO ()
最佳答案
(.)
的左右操作数是
forM_ [stdout, stderr]
flip hPutStrLn
hPutStrLn
的类型是
hPutStrLn :: Handle -> String -> IO ()
flip hPutStrLn
有类型
flip hPutStrLn :: String -> Handle -> IO ()
flip
是一个交换另一个函数参数顺序的组合子。摘要中指定
flip :: (a -> b -> c) -> b -> a -> c
flip f x y = f y x
ghci
你已经知道
(. flip hPutStrLn)
的类型是
ghci> :type (. flip hPutStrLn)
(. flip hPutStrLn) :: ((Handle -> IO ()) -> c) -> String -> c
ghci> :type forM_ [stdout, stderr]
forM_ [stdout, stderr] :: Monad m => (Handle -> m b) -> m ()
(. flip hPutStrLn) :: ((Handle -> IO ()) -> c ) -> String -> c
forM_ [stdout, stderr] :: Monad m => (Handle -> m b ) -> m ()
ghci> :type forM_ [stdout, stderr] . flip hPutStrLn
forM_ [stdout, stderr] . flip hPutStrLn :: String -> IO ()
String
, 并产生一个产生
()
的 I/O 操作,即,我们主要对写入标准输出和错误流的副作用感兴趣。
(.)
组合起来,以更小、更简单的函数来定义更复杂的函数。 .
flip
组合器对于重新排序参数很有用,以便使重复的部分应用程序适合在一起。
关于haskell - 请解释一下 (forM_ [stdout, stderr] .flip hPutStrLn)::String -> IO (),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15115886/
查看 traceIO 的描述,我觉得它的作用正是hPutStrLn stderr做。但是,当我查看它的源代码时: traceIO :: String -> IO () traceIO msg = do
This question already has an answer here: TCP server haskell string comparison (1个答案) 4年前关闭。 我目前正在尝试
我无法理解这个 Haskell 表达式的工作原理: import Control.Monad import System.IO (forM_ [stdout, stderr] . flip hPutS
我是一名优秀的程序员,十分优秀!