Haskell 无绑定重写函数 return
Haskell function rewrite without bind return
根据我收到的建议 ,我正在尝试重写一个没有无关绑定分配的函数 return,但是我被一个额外的 IO 卡住了,我似乎无法理解如何摆脱它。
我有
good :: IO (Either Int String)
getit :: Either Int String -> Int
main :: IO ()
main = do
x <- fmap getit good
putStrLn $ show x
主要工作正常。但是....
main2 :: IO ()
main2 = do
putStrLn $ show $ fmap getit good
-- let's try totally without do
main3 :: IO ()
main3 = putStrLn $ fmap show $ fmap getit good
main2 失败:
• No instance for (Show (IO Int)) arising from a use of ‘show’
• In the second argument of ‘($)’, namely ‘show $ fmap getit good’
In a stmt of a 'do' block: putStrLn $ show $ fmap getit good
In the expression: do { putStrLn $ show $ fmap getit good }
并且 main3 失败:
• Couldn't match type ‘IO’ with ‘[]’
Expected type: String
Actual type: IO String
惯用地重写这个的正确方法是什么?
(子问题:“<-”这个家伙实际上调用了绑定?通过这里:Are there pronounceable names for common Haskell operators?)
你自己,当你在谷歌上搜索“<-”的发音时,你发现我认为你正在寻找:
main4 :: IO ()
main4 = (fmap show $ fmap getit good) >>= putStrLn
从这里开始:
https://wiki.haskell.org/IO_inside
A more complex example involves the binding of variables using "<-":
main = do a <- readLn
print a This code is desugared into:
main = readLn
>>=
(\a -> print a)
但是@Benjamin Hodgson 的回答更好,尤其是完全不需要 fmap 的版本。
对于子问题,“<-”脱糖为绑定,但通过以下方式发音 "is drawn from":https://wiki.haskell.org/Pronunciation
do
符号中的变量绑定将对 bind 组合器的调用脱糖 >>=
:
do { x <- m ; rest } = m >>= \x -> do rest
因此您的示例转换为:
main = fmap getit good >>= \x -> putStrLn $ show x
或者,无点样式:
main = fmap getit good >>= putStrLn . show
或者,利用 fmap
和 >>=
之间的关系:
main = good >>= putStrLn . show . getit
对于许多单子来说,最后一种形式会更有效。 fmap
通常必须重建映射结构(例如,列表的 fmap
运行时间为 O(n)),而函数组合始终为 O(1)。
根据我收到的建议
我有
good :: IO (Either Int String)
getit :: Either Int String -> Int
main :: IO ()
main = do
x <- fmap getit good
putStrLn $ show x
主要工作正常。但是....
main2 :: IO ()
main2 = do
putStrLn $ show $ fmap getit good
-- let's try totally without do
main3 :: IO ()
main3 = putStrLn $ fmap show $ fmap getit good
main2 失败:
• No instance for (Show (IO Int)) arising from a use of ‘show’
• In the second argument of ‘($)’, namely ‘show $ fmap getit good’
In a stmt of a 'do' block: putStrLn $ show $ fmap getit good
In the expression: do { putStrLn $ show $ fmap getit good }
并且 main3 失败:
• Couldn't match type ‘IO’ with ‘[]’
Expected type: String
Actual type: IO String
惯用地重写这个的正确方法是什么?
(子问题:“<-”这个家伙实际上调用了绑定?通过这里:Are there pronounceable names for common Haskell operators?)
你自己,当你在谷歌上搜索“<-”的发音时,你发现我认为你正在寻找:
main4 :: IO ()
main4 = (fmap show $ fmap getit good) >>= putStrLn
从这里开始:
https://wiki.haskell.org/IO_inside
A more complex example involves the binding of variables using "<-":
main = do a <- readLn print a This code is desugared into:
main = readLn
>>=
(\a -> print a)
但是@Benjamin Hodgson 的回答更好,尤其是完全不需要 fmap 的版本。
对于子问题,“<-”脱糖为绑定,但通过以下方式发音 "is drawn from":https://wiki.haskell.org/Pronunciation
do
符号中的变量绑定将对 bind 组合器的调用脱糖 >>=
:
do { x <- m ; rest } = m >>= \x -> do rest
因此您的示例转换为:
main = fmap getit good >>= \x -> putStrLn $ show x
或者,无点样式:
main = fmap getit good >>= putStrLn . show
或者,利用 fmap
和 >>=
之间的关系:
main = good >>= putStrLn . show . getit
对于许多单子来说,最后一种形式会更有效。 fmap
通常必须重建映射结构(例如,列表的 fmap
运行时间为 O(n)),而函数组合始终为 O(1)。