2012-08-26 8 views
5

ユーザーがログインしていることを確認する認可スキームを設定しようとしています。2.ユーザーが特定のオブジェクトにアクセスしています。このために私はまずmaybeAuthIdを呼び出し、現在のオブジェクトを取得しようとし、権限をリストしている別のテーブルに「結合」します。たぶん2つのレベルの多分ケースと1つのレベルの空リストケースがあります。私はMaybeTを使用することを考えましたが、それを動作させるにはあまりにも疲れました。あるいは、実際にはモナドトランスではありません.-ハンドラートランスはMaybeTで使用できません。深いメイズを扱う良い方法はありますか?ディープスタックとyesod

編集:

私は少し不明でした。それはあなたが「深いmaybesを扱う」ことで何を意味するかを正確に明確ではないですが、一度にネストの1つのレベルを削除するには(Control.Monadから)単項joinを使用することができます

case foo of 
    Nothing -> something 
    Just foo' -> do 
     bar <- somethingelse 
     case bar of 
     Nothing -> ... 
     Just bar' -> ... 

答えて

6

Yesodには完全にMaybeTを使用できます。あなたが言ったように、ほとんどの関数は、Yesodの一般的なエラー処理に最適化されていません。しかし、Monad m => m (Maybe a)という形式のものをお持ちの場合は、MaybeTを使ってMonad m => Maybe (m a)に簡単に変換することができます。

+0

ありがとうございました。私は変圧器を使用してからしばらくして、MaybeTでそれらを包む必要があるのを忘れてしまった。 – Masse

1

:私はこのような何かを持っていることを意味しました。

ghci> :m +Control.Monad 
ghci> join (Just (Just 3)) 
Just 3 
ghci> join (Just Nothing) 
Nothing 
ghci> join Nothing 
Nothing 

おそらく、MaybeTを使用する方が問題には適しています。あなたがしようとしていることを明確にするならば、私たちはあなたがMaybeTでそれを公式化するのを手伝うことができます。

2

私が理解から、あなたの層は次のようになります。

Maybe [Maybe r] 

...そして、あなたは2 Maybeは一緒だが、リストが邪魔にあるjoinしたいです。これは正確に問題sequenceが解決されています。この特定のケースで

sequence :: [Maybe r] -> Maybe [r] 

少なくともがあれば、sequenceNothingを返します。我々は我々が得るMaybeモナドへsequenceを専門と、その

sequence :: (Monad m) => [m r] -> m [r] 

注意をリスト内に1つのNothingが含まれていますが、すべてがJustの場合は、それらをすべて1つのJustに結合します。

残っているのは、外Maybesequenceをマッピングすることである。

fmap sequence :: Maybe [Maybe r] -> Maybe (Maybe [r]) 

さて、これはまさに私たちが参加するために必要な形式である:

join . fmap sequence :: Maybe [Maybe r] -> Maybe [r] 

ので、直感的に、どのような機能内部MaybeがすべてJustで、外側がMaybeである場合はJustであり、結果全体を1つのJustに融合しますリスト。ただし、Maybe(内側のものまたは外側のもの)がNothingの場合、最終結果はNothingです。

ブラインドタイプの追いかけをしているにもかかわらず、われわれは直感的に正しいことをする機能に終わったことに注目してください。これはカテゴリ理論に基づいた抽象化の力です。