/ / Jak używać mojego czytnika: newtype R r a = R {run :: r -> a}? - haskell, aplikacyjny

Jak korzystać z mojego czytnika Reader: newtype R r a = R {run :: r -> a}? - haskell, aplikative

Próbuję omówić instancję aplikacyjną programu Reader, dopasowując definicję typu do kilku przykładów. Jednym z problemów jest to, że nie wiem, jak używać mojego nowego typu programu Reader.

Moja definicja czytelnika to

newtype R r a =
R { run :: r -> a }

Definicja typu dla (<*>) jest

(<*>) :: Applicative f => f (a -> b) -> f a -> f b

Specjalnie dla typu czytającego staje się to:

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

Więc kiedy próbuję:

(<*>) (+) (*2) 5 -- seems equivalent to using Reader since the types match

w REPL dostaję 15. Myślę, że to dlatego, że oblicza (2*5) + 5.

Jak mogę to zrobić z moim nowym typem czytnika? I jest a widzisz w (r -> a -> b) to samo a dostajesz od (r -> a) czy też coś nie rozumiem?

Odpowiedzi:

4 dla odpowiedzi № 1

jak powiedziałem w komentarzach, masz w zasadzie wszystko, czego potrzebujesz - brakujący bit to tylko kwestia techniczna zawijania / rozpakowywania funkcji z R konstruktor.

ok, oto jak tworzysz swój R do a Applicative instancja:

instance Applicative (R r) where
pure a          = R (_ -> a)
(R f) <*> (R a) = R (r -> (f r) (a r))

i tak to:

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

to przekłada się na:

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

gdy już to zrobisz, wywołanie odpowiednika twojego przykładu obejmuje po prostu zawijanie / rozpakowywanie funkcji z konstruktora:

run (R (+) <*> R (*2)) 5

w przypadku, gdy pojawi się ostrzeżenie o pliku Functor przykład: potrzebujesz tego też:

instance Functor (R r) where
fmap f (R a) = R (r -> f (a r))