2013-05-09 117 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,你很有可能做错了一些事情(可能在你想调用的代码中)。