我可以使用什么而不是`case of`来减少代码?

时间:2018-05-08 09:46:38

标签: haskell maybe

fmap ( \eachSheet -> case (eachSheet ^. sProperties) of
  Just sheetProperties -> case (sheetProperties ^. sTitle) of
    Just sheets -> (sheetProperties ^. sSheetId)    
    Nothing -> Nothing
  Nothing -> Nothing ) listOfSheets

任何更好的方式来匹配案例

2 个答案:

答案 0 :(得分:7)

特定模式

     case f foo of
       Just bla -> case g bla of
          Just muh -> h muh
       Nothing -> Nothing

Maybe monad 的特征。该实例定义为

instance Monad Maybe where
  return = Just
  Nothing >>= _ = Nothing
  Just x >>= f = f x

因此,您可以将上述case构造重写为

    f foo >>= \bla -> g bla >>= \muh -> h muh

使用do语法

可以使其更具可读性
    do
      bla <- f foo
      muh <- g bla
      h muh

或eta-reduction和Kleisli-composition operator

     (f >=> g >=> h) foo

在您的示例中,后者实际上是不可能的,因为最里面的函数不再使用sheets而是使用sheetProperties,但仍然可以使用do表示法。

答案 1 :(得分:6)

您在此基本上展示的是使用Maybe monad ,因此我们可以将其编写为:

fmap (\s -> (s ^. sProperties) >>= \sheetProperties -> (sheetProperties ^. sTitle) >> (sheetProperties ^. sSheetId)) listOfSheets

由于Maybe monad被定义为:

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

或者我们可以用符号写出来,虽然基本相同:

fmap f listOfSheets
    where f eachSheet = do
        sheetProperties <- eachSheet ^. sProperties
        sheets <- sheetProperties ^. sTitle
        sheetProperties ^. sSheetId