2012-05-06 46 views
2

只是试图让我的头一轮的单子......哈斯克尔了解单子

看这个页面的时刻:http://www.haskell.org/haskellwiki/Simple_monad_examples

在底部,它要求这些片断什么决心:

Just 0 >>= (\ x -> if (x == 0) then fail "zero" else Just (x + 1)) 

为什么这不返回什么?由于失败呼叫?

Nothing >>= (\ x -> if (x == 0) then fail "zero" else Just (x + 1)) 

我明白这一点。

+0

谢谢所有的确认和解释:) – Tobi3

回答

8

在Haskell一如往常,你通常可以通过内联和项重写了解一些代码:

我们:

Prelude> Just 0 >>= (\ x -> if (x == 0) then fail "zero" else Just (x + 1)) 
Nothing 

我们需要的最重要的事情是fail>>=定义为Maybe单子,给出如下:

instance Monad Maybe where 
    (Just x) >>= k  = k x 
    Nothing >>= _  = Nothing 

    (Just _) >> k  = k 
    Nothing >> _  = Nothing 

    return    = Just 
    fail _    = Nothing 

所以我们有:

Just 0 >>= (\ x -> if (x == 0) then fail "zero" else Just (x + 1)) 

-- by definition of >>= 
(\ x -> if (x == 0) then fail "zero" else Just (x + 1)) 0 

-- by definition of fail 
(\ x -> if (x == 0) then Nothing else Just (x + 1)) 0 

-- beta reduce 
if 0 == 0 then Nothing else Just (0 + 1) 

-- Integer math 
if True then Nothing else Just 1 

-- evaluate `if` 
Nothing 

那里你有它。

4

fail的行为取决于单子。在Maybe monad中,fail返回Nothing

instance Monad Maybe where 
    return = Just 

    (Just x) >>= k = k x 
    Nothing >>= _ = Nothing 

    fail _ = Nothing 

然而,在许多其他的单子fail转化为error,因为这是默认的实现。提供自己的fail的单子通常是MonadPlus类中的单子,您可以在fail返回mzero,即 monad中的Nothing

实际上,我不推荐使用fail,因为它不清楚它会做什么。相反,请使用您所在单子的合适失败机制,无论是mzero,throwError还是别的。