2016-04-06 9 views
0

askによってどのようなパラメータが得られますか? よく見ることができますask >>= f 意味はask >>= f = (\k -> f (ask k) k)
ですので、環境からkを得ることができなければなりません。
ただし、ドキュメントには、ask :: m rと記載されています。 どこが間違っていますか?Haskell、ask of parameters

+2

"ask >> = f =(\ k - > f(ask k)k)' "これは間違っています。 – PyRulez

+0

だから私は平等を修正してください。私はそれをここで見つけたhttps://www.haskell.org/wiki/df4e1f5471fe2a2Monads_as_containers –

+0

他の答えは等価を修正する必要があります。 – PyRulez

答えて

1

それはReaderモナドです。最終的に最良の答えはちょうどこのように定義することができ、その実装、バージョン、最も簡単なことで(無モナド変圧器、ノークラス)を研究することである。

newtype Reader r a = Reader { runReader :: r -> a } 

これはnewtype宣言ですので、Reader r aは単に「再ラベルです機能タイプr -> aの(いわば)。 askは、このように定義されています

ask :: Reader r r 
ask = Reader (\r -> r) 

askだけで、独自の引数を返す-the機能再ラベル付け恒等関数であることを意味しています。我々はそれに値を供給するためにrunReader操作を使用している場合我々は、これを見ることができます:

:非常に便利に見えるが、魔法が ReaderFunctorApplicativeMonadのためのインスタンスを持っているという事実から来ていません

ghci> runReader ask 5 
5 

ghci> runReader ask "Hello world!" 
"Hello world!" 

instance Functor (Reader r) where 
    fmap f (Reader g) = 
     -- A `Reader` that applies `f` to the original `Reader`'s results 
     Reader (\r -> f (g r)) 

instance Applicative (Reader r) where 
    pure a = 
     -- A `Reader` that ignores its `r` argument and just produces 
     -- a fixed value. 
     Reader (\_ -> a) 

    Reader ff <*> Reader fa = 
     -- A `Reader` that "combines" two `Reader`s by feeding the same 
     -- `r` value to both, and then combining their results 
     Reader (\r -> ff r (fa r)) 

instance Monad (Reader r) where 
    return = pure 

    Reader fa >>= k = 
     -- A `Reader` that feeds the same `r` both to the original one 
     -- and to the one computed by the `k` function 
     Reader (\r -> k (fa r) r) 

あなたはこれらを勉強すれば、あなたは何Readerことについてですあなたがにラッパーr -> a機能を適用するプログラムのポイントを遅らせていることがわかります。通常、タイプがr -> aで、タイプがaの場合は、タイプrの引数を指定する必要があります。 Readerクラスインスタンスでは、代わりにaで動作するために使用される関数を提供し、最後にrを指定することができます。

ReaderTタイプとMonadReaderクラス(これはask :: MonadReader r m => m rメソッドを持っています)はこれよりも高度なバージョンです。

+0

それは本当であるべきである: 'ask = f = ' –

3

タイプm aの値は、mがMonadである場合、「モナディック・アクション」と考えることができます。したがって、askはパラメータをとらないので、バインダー(>>=)を使用してReaderモナドから値を抽出することができます。 Control.Monad.Trans.ReaderReaderTためaskの定義で

ルック:

-- | Fetch the value of the environment. 
ask :: (Monad m) => ReaderT r m r 
ask = ReaderT return 

ReaderTはタイプr -> m aの値が含まれているだけで、データコンストラクタであるので、ReaderT returnは機能が含まれているタイプReaderT r m rの値であり、return (モナドのm)。

つまり、askは、Readerの内部に格納されている値を抽出する「モナドアクション」です。リーダーのため>>=の定義を使用して

(ReaderT return) >>= f 

ある

ask >>= f 

、我々が得る:

ReaderT $ \ r -> do 
    a <- return r 
    runReaderT (f a) r 

それとも

に減少し
ReaderT $ \ r -> do 
    a <- runReaderT (ReaderT return) r 
    runReaderT (f a) r 

したがって、次のアクションを決定するために格納された値を渡し、次のアクションが前と同じように値を渡すようにします。

(これは明確ではなかった場合は、おそらく読者のチュートリアルを探してください)

+0

rの意味は何ですか? –

+1

@HaskellFun '\ r - > ... 'という構文が' r'パラメータの意味を聞いていますか? –

+0

何を表していますか?私はこの構文を知っている、ちょうどラムダ:) –