2016-11-28 20 views
7

Ben Learn you a haskell kitabın içinden gidiyorum ve Bölüm 8'de Bu işler buHaskell - case ifadesi

data LockerState = Taken | Free deriving (Eq, Show) 
type Code = String 
type LockerMap = Map.Map Int (LockerState, Code) 

lookup' :: Int -> LockerMap -> Either String Code 
lookup' num_ map_ = 
    case (Map.lookup num_ map_) of 
     Nothing -> Left $ "LockerNumber doesn't exist!" 
     Just (state, code) -> if state == Taken 
           then Left $ "LockerNumber already taken!" 
           else Right $ code 

benzeyen bir kod parçacığı vardır içeride bekçi. Ancak,/else bloğu aşağıdaki gibi Açıklama deyimine dönüştürmek istedim:

Bu, derleme değil. Haskell'deki gardiyanların kullanımının çok kısıtlayıcı/sezgisel olmadığı görülmektedir. SO Ex1SO Ex2. Muhafızları hangi yerlerde kullanabileceğimi okuyabileceğim kesin bir kaynak var mı?

cevap

18

İki noktaya izin verilir: işlev tanımları ve case ifadeleri. Her iki örnekte de, gardiyanlar önce bir desen ve vücut sonra görünür, bu yüzden her zamanki gibi case branşta fonksiyonlarda = ve -> kullanın:

divide x y 
    | y == 0 = Nothing 
    -------- 
    | otherwise = Just (x/y) 
    ----------- 

positively mx = case mx of 
    Just x | x > 0 -> Just x 
     ------- 
    _ -> Nothing 

Muhafızları kısıtlamalar kalıpları için böylece, sade Just x, Nothing değeriyle eşleşir, ancak Just x | x > 0 yalnızca sarılmış değeri de pozitif olan bir Just ile eşleşir.

ben kesin referans özellikle gardiyan sözdizimi açıklanmaktadır ve onlar izin nereye belirtmek § 3.13 Vaka İfadeler ve § 4.4.3 Fonksiyon ve Desen Bağlar, Haskell Report olduğunu varsayalım. Kodunuzda

, istediğiniz:

Just (state, code) 
    | state == Taken -> Left "LockerNumber already taken!" 
    | otherwise -> Right code 

Bu aynı zamanda tek başına desenleri ile baskısının yapılabildiği:

Just (Taken, _) -> Left "LockerNumber already taken!" 
Just (_, code) -> Right code 
+1

Büyük cevabı! Özellikle 'Korumalar' kalıplar için sadece kısıtlamalar – skgbanga