2016-10-15 36 views
6

Haskell Book、「第22章リーダー」でエクササイズができません。演習では、「リーダーのためのApplicativeを実装」と言うと、それは次のようになります:Readerのアプリケーションインスタンスを書き込むときに<*>を書き込む方法

{-# LANGUAGE InstanceSigs #-} 

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

instance Applicative (Reader r) where 
    pure :: a -> Reader r a 
    pure a = Reader $ ??? 

    (<*>) :: Reader r (a -> b) -> Reader r a -> Reader r b 
    (Reader rab) <*> (Reader ra) = Reader $ \r -> ??? 

私はそうGHCはありません「文句れたので(私は、Functorインスタンスを書いてもFunctorインスタンスを書き込んだ後pureを書くことができました「‘Applicative (Reader r)’のインスタンス宣言では、インスタンス宣言のスーパークラスから生じる(Functor (Reader r)) …)のインスタンス:

{-# LANGUAGE InstanceSigs #-} 

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

instance Functor (Reader r) where 
    fmap f (Reader x) = Reader (f . x) 

instance Applicative (Reader r) where 
    pure :: a -> Reader r a 
    pure a = Reader $ \_ -> a 

    (<*>) :: Reader r (a -> b) -> Reader r a -> Reader r b 
    (Reader rab) <*> (Reader ra) = Reader $ \r -> ??? 

しかし、私は???部分でこだわっています。私たちは、あなたが何をする必要があるかを説明 よ、適用する関数の定義があなたのために始めました

、あなたがコードを書く:

本は、以下のヒントを提供します。上記のReader's applyのタイプ を解凍すると、次のようになります。

<*> :: (r -> a -> b) 
    -> (r -> a) 
    -> (r -> b) 

-- contrast this with the type of fmap 

fmap :: (a -> b) 
    -> (r -> a) 
    -> (r -> b) 

だから違いは何ですか?違いはapplyで、 fmapと異なり、rという引数もあります。

はい、どうすればいいですか? 型付き穴を使用すると、コンパイラは???の型がbである必要があることを通知します。しかし、私はまだrを受け取り、タイプbrabraを返すラムダ式をどのように構築できるか分かりません。

+0

また、その本を購入しない私たちのために、「リーダー」データタイプの定義を提供できますか? –

+0

@Rhymoidこれは少し厳しいです。 「リーダー」とは、結局のところ一般的な知識です。 – duplode

+0

申し訳ありませんが、Readerタイプが見つからないため、上記の質問に追加しました。 –

答えて

7

あなたはスコープを持っている作品、

rab :: r -> (a -> b) 
ra :: r -> a 
r :: r 

bの目標タイプを見ると、あなたがbアウトを得ることができる唯一の方法はrab 2の引数を適用していることがわかります。

Reader rab <*> Reader ra = Reader $ \r -> rab _ _ 

さて、最初の穴はrの種類があり、あなただけの範囲内の1つのrを持っています。

残りの穴のタイプはaです。あなたはスコープを持っているだけaraの戻り値である、

Reader rab <*> Reader ra = Reader $ \r -> rab r (ra _) 

raの引数には、もう一度、あなたが唯一の選択肢を持っているr、でなければなりません。

Reader rab <*> Reader ra = Reader $ \r -> rab r (ra r) 

rabraは両方の引数としてr受けることに注意してください。合成されたReader計算のすべてのステップは、同じ環境にアクセスできます。

なお、この定義では、は、有名なS combinator(およびpureK)に相当します。

関連する問題