3

私は(限られた)Haskellの知識をSnap Webフレームワークに適用し、何を構築できるかを確認しています。(おそらく存在しない)パラメーターを取得し、それをintに解析しようとしています。明らかに「たぶん」は私が欲しがっているものです。

以下のコードでAppHandlerは、次のように定義されていHandler App Appます(チュートリアルでは現在何も見つかりませんが、2つのレベルの状態を持つモナドだと思います)。でB8ありByteString.Char8readInt戻りますMaybe(Int,ByteString)

以下のコードは機能しますが、おそらく呼び出しを連鎖させる方法があるはずです(おそらく、私はすでにモナドにいるので、MaybeTを介して)。次のステップは、解析されたIDに基づいてデータベースから行をフェッチすることであるため、連鎖は特に意味があります。もちろん、それは「多分a」も返します。明らかに、これは非常に一般的なパターンです。

-- Given a parameter name, return the Int it points to
-- or Nothing if there is some problem
maybeIntParam :: ByteString -> AppHandler (Maybe Int)
maybeIntParam pname = do
    raw_param <- getParam pname
    let mb_i_b = maybe (Nothing) B8.readInt raw_param
    case mb_i_b of
        Nothing    -> return Nothing
        Just (p,_) -> return $ Just p

runMaybeTを適用してみましたが、率直に言ってどのタイプを変更する必要があるのか​​がよくわからず、エラーがなくなることを期待してランダムに変更していました。それは変化し、行から行へと動き回ったが、そうではなかった。

Haskellを探索し始めたときよりもはるかに高いレベルで完全に失われているので、これを進歩として扱っています...


編集:kosmikusの答えを歩いて、うまくいけば私はそれを理解しました...

1 maybeIntParam :: ByteString -> AppHandler (Maybe Int)
2 maybeIntParam pname = do
3     raw_param <- getParam pname
4     return $ do
5       param  <- raw_param
6       (p, _) <- B8.readInt param
7       return p

私はこれに向かって少しずつ努力していたと思いますがgetParam、他のステップと同じブロック内に強制しようとし続けました。

3行目では、getParamの呼び出しがAppHandlerで行われています。であるraw_paramがありMaybe ByteStringます。5行目では、ネストされたdoにいるので、バインディング(?)はMaybeモナド内で行われ、paramaByteStringまたはgetのいずれかになり、残りのdoブロックは*Nothingを短絡します。同様に、6行目では、pはIntであるか、または短絡しています。

6行目にpはInt(たとえば42)が含まれており、7行目は。を返しJust 42ます。になる4行目に戻りAppHandler (Just 42)ます。現時点でAppHandlerが何であるかを気にする必要はありません-タイプはすべて満足しています。

これもタイプチェックであり、これを考え抜こうとしている人に役立つかもしれないいくつかのバリエーションがあります。

maybeIntParam1 :: ByteString -> AppHandler (Maybe Int)
maybeIntParam1 pname = do
    raw_param <- getParam pname
    let mb_int_param = do
        param  <- raw_param
        (p, _) <- B8.readInt param
        return p
    return mb_int_param

maybeIntParam2 :: ByteString -> AppHandler (Maybe Int)
maybeIntParam2 pname = do
    return $ return 27

maybeIntParam3 :: ByteString -> AppHandler (Maybe Int)
maybeIntParam3 pname = do
    return (Just 27)

この場合、非実行バリエーションは実際には単純に見えます。考える必要があるのは、<$>私が正しく読んでいる場合は、fmapを適用しfstMaybe (Int,ByteString)取得できるようにすることだけですMaybe Int


*正しく理解していれば、後続の各行にアクセスする必要がありますが、Nothingを返すだけなので、実際にはgotoスタイルのショートカットではありません。 Edit2:以下のkosmikusのコメントを参照してください-怠惰+右ネストは、各行を評価する必要がないことを意味します。

4

1 に答える 1

7

Maybeここでモナドをローカルで使用できます。

maybeIntParam :: ByteString -> AppHandler (Maybe Int)
maybeIntParam pname = do
    raw_param <- getParam pname
    return $ do
      param  <- raw_param
      (p, _) <- B8.readInt param
      return p

Maybeまたは、必要に応じて、 -computationsをワンライナーとして記述できます。

maybeIntParam :: ByteString -> AppHandler (Maybe Int)
maybeIntParam pname = do
    raw_param <- getParam pname
    return $ fst <$> (raw_param >>= B8.readInt)

関係するタイプのいくつか:

raw_param                          :: Maybe ByteString
B8.readInt                         :: ByteString -> Maybe (Int, ByteString)
raw_param >>= B8.readInt           :: Maybe (Int, ByteString)
fst                                :: (Int, ByteString) -> Int
fst <$> (raw_param >>= B8.readInt) :: Maybe Int
于 2013-02-26T15:33:47.730 に答える