リストタイプにReader
/ ReaderT
toを使用するにはどうすればよいですか?ask
たとえば[(Int, Int)]
、(ask
編集されたタイプの)リストモナド内で計算を実行しますか?
私の壊れたコードは次のとおりですが、わかりやすくするために短縮されています。
attempt :: Int -> Int -> ReaderT [(Int,Int)] [] [[Int]]
attempt start end =
do (s0, e0) <- ask
return [0]
私がやろうとしていることを理解するために、ここに同じ関数があります。リストモナドを使用していますが、リーダーは使用していません。
paths :: [(Int, Int)] -> Int -> Int -> [[Int]]
paths edges start end =
if start == end
then return [end]
else do (s0, e0) <- edges
guard $ s0 == start
subpath <- paths edges e0 end
return $ s0 : subpath
私はモナド変換子を学んでいるので、ReaderTを使用しています。これは、リーダーとライターの両方を使用し、モナドをリストしてパスを実装するという、より大きな問題の一部です。
ここでの秘訣は、liftを使用して、次を使用してリストモナド(つまり、[a]
)をに変換するReaderT env []
ことlift
です。
lift :: (Monad m, MonadTrans t) => m a -> t m a
またはモナドスタックに特化:
lift :: [a] -> ReaderT [(Int,Int)] [] a
ask
モナドに[(Int, Int)]
ラップされた状態(つまり)を返します。ReaderT
例:
ask :: ReaderT [(Int, Int)] [] [(Int, Int)]
同じモナドで、次のタイプの別の値に変換します。
??? :: ReaderT [(Int, Int)] [] (Int, Int)
したがって、代替案は、出力ではなくモナドによって追跡されます。基本的な機能を考えてみましょう>>=
:
(>>=) :: Monad m => m a -> (a -> m b) -> m b
必要なすべての部品が揃っていることがわかります。使用ask >>= lift
:
ReaderT [(Int, Int)] [] [(Int, Int)]
意味では、a
あり[(Int, Int)]
、そしてm
ありますReaderT [(Int, Int)] []
m b
するReaderT [(Int, Int)] [] (Int, Int)
ので、b
あります(Int, Int)
[(Int, Int)] -> ReaderT [(Int, Int)] [] (Int, Int)
です。関数a
内のをに置き換えると、完全に一致します。つまり、式が必要なことを実行します。lift
(Int, Int)
ask >>= lift
もう1つの間違いは、ReaderT
モナドの出力タイプでした。リストモナドが含まれていたため、結果を別の角かっこで囲む必要はありませんでした。にはReaderT state []
すでに複数の結果の概念が含まれており、この場合の単一の結果[Int]
はグラフパスを示しています。
動作するコードは次のとおりです。
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
module Main where
import Control.Monad.Reader
import Control.Applicative
paths :: Int -> Int -> ReaderT [(Int,Int)] [] [Int]
paths start end = do
if start == end
then return [end]
else do
(s0, e0) <- ask >>= lift
guard $ s0 == start
(s0 :) <$> paths e0 end
input :: [(Int, Int)]
input = [(1,2), (2,7), (3,4), (7, 3), (7, 5), (5, 3)]
test :: [[Int]]
test = runReaderT (paths 2 4) input
> test
[[2,7,3,4],[2,7,5,3,4]]
それがそれを明確に説明していることを願っています。この状況では、おそらく元の解決策に固執するでしょう(Reader
通常、それ自体を使用することはあまり役に立ちません)が、モナドとモナド変換子のタイプを理解して操作する方法を知っておくのは良いことです。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加