2016-12-23 62 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