Haskell函数重写没有绑定返回

时间:2016-12-23 23:12:37

标签: haskell pointfree

根据我收到的建议here,我试图重写一个没有无关的绑定并返回的函数,但是我遇到了额外的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

正确重写此内容的正确方法是什么?

(子问题:是&#34;&lt; - &#34;这家伙实际上叫做绑定?来自:Are there pronounceable names for common Haskell operators?

2 个答案:

答案 0 :(得分:5)

do中的变量绑定 - 符号desugars调用 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

对于许多monad来说,这最后一种形式会更有效率。 fmap经常需要重建映射结构(例如,列表'fmap在O(n)时间运行),而函数组合总是O(1)。

答案 1 :(得分:2)

自我,当你搜索“&lt; - ”的发音时,你发现我认为你在寻找:

main4 :: IO ()
main4 = (fmap show $ fmap getit good) >>= putStrLn

从这里开始:

https://wiki.haskell.org/IO_inside

  

更复杂的例子涉及使用“&lt; - ”:

绑定变量      

main =做一个&lt; - readLn             打印a此代码被删除:

     

main = readLn         >>=(\ a - &gt;打印a)

但@Benjamin Hodgson的答案更好,特别是那个根本不需要fmaps的版本。

对于子问题,“&lt; - ”desugars to bind,但发音为“from from”via:https://wiki.haskell.org/Pronunciation