2013-05-09 121 views
1

什麼是用下面的代碼的問題:我想要的搜索列表的匹配,並返回一個函數Haskell的IO功能類型不匹配

src\Main.hs:364:10: 
    Couldn't match expected type `(IO a, t0)' with actual type `IO a' 
    In a stmt of a 'do' block: s <- x 
    In the expression: 
     do { s <- x; 
      if f s then (return x, xs) else nextMatch f xs } 
    In an equation for `nextMatch': 
     nextMatch f (x : xs) 
      = do { s <- x; 
       if f s then (return x, xs) else nextMatch f xs } 

nextMatch :: (a -> Bool) -> [IO a] -> (IO a, [IO a]) 
nextMatch f (x:xs) = do 
    s <- x 
    if f s then (return x, xs) 
     else nextMatch f xs 

編譯錯誤說匹配元素加上剩下的列表,作爲元組。

我還是很新的哈斯克爾,所以這個問題可能是一個很簡單的......

謝謝! Chris

+4

一般性評論 - 一元參數(例如'IO [a]'或您的[IO a]')幾乎總是一個壞主意。不純代碼通常需要純粹的參數,使用do-notation或'>> ='將它們應用於monadic值。 – isturdy 2013-05-09 19:34:56

回答

1

由於x如果類型爲IO a,不需要重新返回它,這與確實需要注入到monad中的元組相反。

if f s then return $ (x, xs) 

但是,這並不是唯一的問題,因爲你是到IO單子和你的簽名並不能反映它,當你返回類型爲(IO a, [IO a])應該IO (IO a, [IO a])。 然後你的代碼應該如下。

nextMatch :: (a -> Bool) -> [IO a] -> IO (IO a, [IO a]) 
nextMatch f (x:xs) = 
    do 
    done <- fmap f x 
    if done 
    then return $ (x, xs) 
    else nextMatch f xs 

無論如何,我不知道你要做什麼,但你的功能的簽名看起來很尷尬。它應該看起來更像nextMatch :: (a -> Bool) -> [a] -> (a, [a]),然後使用return就足以構建它的monadic版本。 nextMatchIO = return $ nextMatch,然後使用Control.Monad提供的其他函數將此計算插入到您的控制流中。

+0

你不需要'$'在這些版本的... – 2013-05-09 17:06:12

+0

你是對的,但要避免額外的計算這是痛苦的我的大腦我把大部分時間我會用'return $ expr'代替'return expr'。當然,當我編寫專業代碼時,這個規則不適用,那麼我花時間問我是否必須使用'$'。無論如何感謝您的評論。 – zurgl 2013-05-09 17:22:16

+0

@zurgl我最近得出結論,我需要在單代碼中使用'*'少得多*。這使得使用'>> ='或應用風格移動東西變得很痛苦,因爲我一直在想,我可以轉換'a < - g $ b; f'到'g $ b >> = f',或到'f <$> g $ b'。 – Ben 2013-05-11 04:13:11

-1

你的函數應該返回一個元組。如果我的Haskell仍然達到標準,那麼我會嘗試在你的返回函數的周圍放置parens「if fs then(return(x,xs))」。

+1

您Haskell是不是還在「達到標準」 :) – is7s 2013-05-10 09:27:53

9

您不應該在這裏處理IO。這是我想實現它作爲一個純函數(我加了Maybe類型,因爲有可能不是下一場比賽):

nextMatch :: (a -> Bool) -> [a] -> Maybe (a, [a]) 
nextMatch _ []  = Nothing 
nextMatch f (x:xs) = if f x then Just (x, xs) else nextMatch f xs 

作爲一個初學者,如果你正在做一些與IO作爲輸入到一個函數,或者如果你返回的數據結構裏面有IO,你很有可能做錯了一些事情(可能在你想調用的代碼中)。