2016-10-31 8 views
1

誰かがgetDogR1を実行する方法を説明してください。 <$><*>の両方にパラメータが必要です。しかし、Readerタイプは関数ではなく、パラメータもありません。では、Personデータ型をどのように渡すのですか?たとえば、(getDogRの実行方法はgetDogR pers)を使用してgetDogR1を実行することはできません。例えば<*> for Readerの実装

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

instance Functor (Reader r) where 
    fmap f (Reader f1) = Reader $ f . f1 

instance Applicative (Reader r) where 
    pure :: a -> Reader r a 
    pure a = Reader $ const a 
    (<*>) :: Reader r (a -> b) -> Reader r a -> Reader r b 
    Reader rab <*> Reader ra = Reader $ \r -> rab r (ra r) 
----------------------------------------------------------------- 
newtype HumanName = HumanName String deriving (Eq, Show) 
newtype DogName = DogName String deriving (Eq, Show) 
newtype Address = Address String deriving (Eq, Show) 

data Person = Person { 
       humanName :: HumanName 
       , dogName :: DogName 
       , address :: Address 
       } deriving (Eq, Show) 

data Dog = Dog { 
      dogsName :: DogName 
      , dogsAddress :: Address 
      } deriving (Eq, Show) 

pers :: Person 
pers = Person (HumanName "Big Bird") 
       (DogName "Barkley") 
       (Address "Sesame Street") 

dDuck :: Person 
dDuck = Person (HumanName "Jeff") 
       (DogName "Mutley") 
       (Address "Some Street") 

getDog :: Person -> Dog 
getDog p = Dog (dogName p) (address p) 

getDogR :: Person -> Dog 
getDogR = Dog <$> dogName <*> address 

getDogR' :: Person -> Dog 
getDogR' = liftA2 Dog dogName address 

getDogR1 :: Reader Person Dog 
getDogR1 = Dog <$> Reader dogName <*> Reader address 

答えて

3

使用runReader

runReader getDogR1 pers 

Readerは、単にタイプr -> aの機能の周りのnewtypeとrunReaderが自動的にフィールドのアクセッサ関数を生成し、その(のみ)フィールドの名前であります同じ名前でReaderの値にこの値を使用すると、基礎となる関数が抽出され、getDogRのように処理を続けることができます。

+0

Ahhはい。どうもありがとう。 – user1897830

関連する問題