2014-01-15 62 views
0

我想從「failable」數據類型中輕鬆獲取某個值,或者在發生故障時使用默認值。「應用默認值」的抽象形式

這是我爲Maybe實現:

infixr 1 <||> 
(<||>) :: Maybe a -> a -> a 
(<||>) = flip fromMaybe 

pred :: String -> String -> Bool 
pred x name = (x ==) <$> name `lookup` myMap <||> False 

pred返回True如果name映射到xmyMap

但正如Haskell通常的情況一樣,有一種更抽象的方式來做到這一點,我不知道。任何人?

+0

'也許假(x ==)$查找名myMap' – augustss

+0

是的,我想的太,但我在尋找更多的抽象。 –

+1

問題在於,沒有真正的方法可以將'fromMaybe'抽象出來,因爲在一般情況下,函子不允許您提取已包裝的值。你總是需要一個'Maybe'特定的函數,根據你的編寫方式,函數可能是'fromMaybe','fromJust'或'maybe'。 – Tarmil

回答

4

Foldable可能是標準庫中的一個合理的選擇:

import Data.Foldable 

infixr 1 <||> 
(<||>) :: Foldable f => f a -> a -> a 

v <||> a = 
    case toList v of 
     [] -> a 
     (x:xs) -> x 

它意味着你必須決定是否採取發現了「第一」要素或「最後」一個雖然。不幸的是,它還沒有Either實例,儘管它是coming in GHC 7.8/base 4.7。在此期間,你可以自己定義:

instance Foldable (Either a) where 
    foldMap _ (Left _) = mempty 
    foldMap f (Right y) = f y 

    foldr _ z (Left _) = z 
    foldr f z (Right y) = f y z 
+0

任何原因爲什麼它沒有這兩個實例? –

+2

我只是在研究這個。本質上,我認爲它正在等待:http://www.haskell.org/pipermail/libraries/2012-July/018248.html,但我不太確定它是否已登陸或尚未登陸。 –

0

這就是我想出了:

class Defaultable f where 
    infixr 1 <||> 
    (<||>) :: f a -> a -> a 

instance Defaultable Maybe where 
    (<||>) = flip fromMaybe 

instance Defaultable (Either a) where 
    (Left _) <||> x = x 
    (Right x) <||> _ = x 

加上Alternative,你可以串起來可能的選擇,並在最後一個默認值。