簡體   English   中英

B計划,或者與Maybe的相反的是>> =?

[英]Plan B, or what's the opposite of Maybe's >>=?

我們來看兩個功能:

f :: a -> Maybe b
g :: b -> Maybe c

函數>>=將以這樣的方式工作: f >>= g只有當它不是Nothing時才用f的結果執行g 換句話說,它需要fg都能成功產生任何結果。

我正在實現一個解析器,並意識到我的詞法分析器會從中獲益。 那是:

f :: a -> Maybe b
g :: a -> Maybe b

planb :: (a -> Maybe b) -> (a -> Maybe b) -> (a -> Maybe b)
planb f g = \x -> case f x of
                      Nothing -> g x
                      res -> res

這意味着嘗試f ,如果失敗,請嘗試g作為備份計划。 使用詞法分析器意味着嘗試將令牌類型與當前輸入匹配,如果失敗,請嘗試匹配另一個令牌類型(最終將為所有令牌類型鏈接)。

搜索Hoogle沒有導致任何這樣的功能,但對我來說這樣的功能似乎在很多地方都很有用!

我的問題是,我是否應該使用planb的變體? 如果沒有,我是否做了非凡的事情,有更好的方法來達到我想要的目標?


PS我想到這樣的功能對於Monad來說是否有意義,但是對於我在Maybe之外並沒有那么多意義, Maybe還有其他一些。

Alternative類型正是這樣做的,它與MonadPlus非常相似,但可能更為通用。

import Control.Applicative

-- most general form
planb :: (Applicative g, Alternative f) => g (f a) -> g (f a) -> g (f a)
planb = liftA2 (<|>)

-- specialized to (->) and Maybe
planb' :: (a -> Maybe b) -> (a -> Maybe b) -> (a -> Maybe b)
planb' = planb

-- equivalent to planb' (and planb) but without the fancy combinators
planb'' :: (a -> Maybe b) -> (a -> Maybe b) -> a -> Maybe b
planb'' f g x = f x <|> g x

將其插入一個簡單的測試用例:

test :: Maybe Int
test = do
  a <- planb' (const Nothing) id (Just 1)
  b <- planb' id id (Just 1)
  c <- planb' id (const Nothing) (Just 1)
  return $ a + b + c

生成預期結果:

*Main> test
Just 3

請注意,您的planb函數實際上只需要對Maybe值進行操作; 調用函數來生成它們可以被考慮在內。

planb :: Maybe a -> Maybe a -> Maybe a
planb Nothing b = b
planb a _ = a

你會把它planb (fx) (gx)來得到一個Maybe結果。

考慮到這一點,請查看MonadPlus (正如Franky在評論中所建議的那樣):

planb = mplus

您可能還對msum感興趣, msum會獲取Maybe值列表並返回第一個(如果有)不是Nothing 這是一個方便的功能:

matchSomehow :: [a -> Maybe b] -> a -> Maybe b
matchSomehow fs a = msum $ map ($a) fs

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM