2017-04-22 134 views
1

我有這樣的功能:IO序列哈斯克爾

sequence :: [IO a] -> IO [a] 
sequence [] = pure [] 
sequence (op:ops) = do 
    x <- op 
    xs <- sequence ops 
    return (x:xs) 

剛剛寫入的IO操作的順序。

問題是我想編寫相同的函數,但是完全不使用'do notation',只是使用操作符>>和>> =來代替。

我已經有該版本:

mySequence:: [IO a]-> IO [a] 
mySequence [] = pure [] 
mySequence (op:ops) = 
    op >> sequence ops 

但它不會例如與輸入[純1,純2]工作。

任何人都可以幫助我嗎?

在此先感謝。

+0

在'do'版本中,您有2個綁定和一個return語句。在沒有'do'的版本中,你使用'>>',它放棄了它左邊的操作數的結果,並且你唯一返回的是'[]'。 'do'版本也使用':'運算符,而''''''''''版本不支持。 – sepp2k

回答

1

在應用性的符號,這是相當簡單:

sequence (op:ops) = (:) <$> op <*> sequence ops 

林單子符號,只是翻譯do,同時保持其結構:

sequence (op:ops) = 
    op    >>= \x -> 
    sequence ops >>= \xs -> 
    return (x:xs) 

粗略地說,x <- action; ...變得action >>= \x -> ...。請注意,上述lambda表達式的範圍一直延伸到表達式的最後。使用明確的括號:

sequence (op:ops) = 
    op >>= (\x -> sequence ops >>= (\xs -> return (x:xs))) 
+0

感謝您的回答。 如果我們調用如下函數:sequence [putStr「hi」,pure 4], 這不起作用,爲什麼? –

+1

@AntonioSerrano什麼是'[putStr「hi」,純4]'的類型? 'putStr「hi」'和'pure 4'具有不兼容的類型,你不能把它們放在同一個列表中(除非你創建了一個'instance Num()',我想)。 – sepp2k

+0

好的,我明白了,但爲什麼以[純1,純2]爲例仍然不起作用? @ sepp2k –