1

私はしばしば、「たぶん何もない someFunc」パターンを持つコードを持っています:

instance FromJSON SaveSection where
  parseJSON (Object o) =
      SaveSection <$>
      o .:? "eventId" <*>
      (maybe Nothing parseUSDate <$> o .:? "eventDate") <*>
      o .:? "eventRecId" <*>
      o .:? "idxId" <*>
      (maybe Nothing parseUSDate <$> o .:? "idxDate") <*>
      o .:? "idxRecId"

ここparseUSDateに type がありText -> Maybe Dateます。

Aeson 解析は明らかに を返しますMaybe Text

だから私はここの2つの層を持ち上げる必要があるように私には見えMaybeます. maybe Nothing someFuncそして、パターン以外の方法でそれを行う方法がわかりません。

ここで使用できる明らかな「平坦化」またはその他の機能が不足していますか?

編集:アレクセイの答えをありがとう。

これはまさに私が探していたものです。最終結果は次のとおりです。

instance FromJSON SaveSection where
  parseJSON (Object o) =
      SaveSection <$>
      o .:? "eventId" <*>
      ((>>= parseUSDate) <$> o .:? "eventDate") <*>
      o .:? "eventRecId" <*>
      o .:? "idxId" <*>
      ((>>= parseUSDate) <$> o .:? "idxDate") <*>
      o .:? "idxRecId"
4

2 に答える 2

10

非常に便利なControl.Monad.join機能があります:

> join (Just (Just 1))
Just 1
> join (Just Nothing)
Nothing
> join Nothing
Nothing

私は Aeson の専門家ではありませんが、専門家なら:

> :m Control.Monad Control.Applicative Data.Aeson Data.Text
> :set -XOverloadedStrings
> :set +m 
> let f :: Text -> Maybe Text
|     f = Just    -- Stand-in for parseUSDate
> :t \o -> join <$> liftM f <$> o .:? "key"
Object -> Parser (Maybe Text)
> -- Has the same type as your expression
> :t \o -> maybe Nothing f <$> o .:? "key"
Object -> Parser (Maybe Text)

それはあなたが探しているものですか?

編集:実際に機能するように修正しました...私の最初のジェネリックf :: a -> Maybe aは混乱していました。


これをクリーンアップするオペレーターを作成できます。

infixl 9
(>>=$) :: (Functor f, Monad m) => f (m a) -> (a -> m b) -> f (m b)
m >>=$ a = join <$> liftM a <$> m

parseJSON (Object o) =
    SaveSection
        <$> o .:? "eventId"
        <*> o .:? "eventDate" >>=$ parseUSDate
        <*> o .:? "eventRecId"
        <*> o .:? "idxId"
        <*> o .:? "idxDate" >>=$ parseUSDate
        <*> o .:? "idxRecId"

(これはうまくいくはずです...)

于 2014-03-31T17:45:20.073 に答える
6

がある場合f' = maybe Nothing f、型はand である必要がf :: a -> Maybe bありますf' :: Maybe a -> Maybe b(ここでa、 andbは変数または特定の型である可能性があります)。そうしないと、型チェックされません。しかし、これは単にモナドの型>>=です: ! のように書ける。MaybeMaybe a -> (a -> Maybe b) -> Maybe bmaybe Nothing f(>>= f)

于 2014-03-31T18:19:55.723 に答える