2010-12-14 52 views
4

我有以下代码:有没有标准的功能“如果只是x做这个”?

doIf :: (a -> IO()) -> Maybe a -> IO() 
doIf f x = case x of 
    Just i -> f i 
    Nothing -> return() 

main = do 
    mapM_ (doIf print) [Just 3, Nothing, Just 4] 

,其输出:

3 
4 

换句话说,被印刷在Just值,但Nothing值会导致无动作。 (并且不要中断计算。)

在Haskell库中是否有这样的标准函数?另外,这可以变得更通用吗?我试图用m b替换IO(),但return()不起作用。你怎么一般写return()任何单子? (如果可能的话)甚至可以在这里推广Maybe

最后,我可以完全废除doIf函数吗?我可以让运营商<#>应用参数,除非Nothing

print <#> Just 3 
print <#> Nothing 

将输出

3 

但我不知道这是可能的。

+0

关于它的思考,我想这是不大不小的一元的“同”。 – Steve 2010-12-14 03:05:49

回答

7

doIfData.Foldable.traverse_一个特例。

通常你可以通过Hoogle找到这类东西,但目前它似乎有点破碎。在我的系统上安装的命令行版本为Data.Foldable.traverse_作为查询(a -> IO()) -> Maybe a -> IO()的第一个结果。


而且,当然,你可以定义运营商,它只是(<#>) = doIf(或(<#>) = Data.Foldable.traverse_)。

+0

谢谢,哇,“遍历”不是我想到的那个名字的名字。 – Steve 2010-12-14 03:34:25

+1

对于其他Foldable/Traversable实例(如数组)更有意义。你可以将一个Maybe值看作最多一个长度列表,在这种情况下,你的函数“遍历”该列表。 – 2010-12-14 03:45:36

+0

有道理,谢谢。 – Steve 2010-12-14 04:11:11

17

看看功能:

maybe :: b -> (a -> b) -> Maybe a -> b 

你几乎写它在doIf除了固定return()

+0

啊哈,谢谢!不知何故,我在考虑monadic代码,并没有考虑查看没有某种“mb”签名的函数。 – Steve 2010-12-14 03:32:36

+1

是的,'IO()'只是另一种类型,在这里可以是'b'。 – dino 2010-12-14 04:20:56

5

你能线沿线的财产以后做:

main = do 
    mapM_ print $ catMaybes [Just 3, Nothing, Just 4] 

catMaybes参见文档。

(注:未经测试的代码)

+3

我喜欢这种方法。将问题分解成更小的问题,并且远离IO。 – dino 2010-12-14 15:40:52

相关问题