2016-12-23 61 views
1

在建议我收到here,我试图重写一个函数没有多余的绑定分配和返回,但是被一个额外的IO阻塞我似乎无法理解如何摆脱它。Haskell函数重写没有绑定返回

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?

回答

5

可变结合在do -notation desugars到来电来绑定组合子>>=

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)。

+0

而且'print = putStrLn。 show',所以'main = good >> = print。 getit' – freestyle

2

自我,当你用Google搜索如何发音“< - ”你发现,我觉得你寻找:

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

从这里:

https://wiki.haskell.org/IO_inside

一个更复杂的例子涉及使用 “< - ” 变量绑定:

主要=做< - readLn 打印一个该代码被脱糖成:

主要= readLn >>=(\ A - > print a)

但是@Benjamin Hodgson的回答更好,尤其是不需要fmaps的版本。 -

而到了subquestion,“<” desugars的绑定,但发音通过“从绘制”:https://wiki.haskell.org/Pronunciation