비맵으로 놀아요.
newtype WriterT w m a = WriterT { runWriterT :: m (a, w) }
Functor 인스턴스
Functor의 인스턴스는 적분 없이 간단하게 작성할 수 있습니다.
import Data.Bifunctor (first)
instance Functor m => Functor (WriterT w m) where
fmap :: (a -> b) -> WriterT w m a -> WriterT w m b
fmap f = WriterT . fmap (first f) . runWriterT
Applicative Functor 인스턴스
그런 다음 Applicative Functor의 인스턴스를 작성합니다.
instance (Applicative m, Monoid w) => Applicative (WriterT w m) where
pure :: a -> WriterT w m a
pure a = WriterT $ pure (a, mempty)
이 정의를 면적분으로 설정하는 것은 아까보다 더 어려운 것 같지만 간단하다.import Data.Bifunctor (second)
import Control.Monad (join)
instance (Applicative m, Monoid w) => Applicative (WriterT w m) where
pure :: a -> WriterT w m a
pure = WriterT . pure . second (const mempty) . join (,)
<*>
도 정의해 보세요.instance (Applicative m, Monoid w) => Applicative (WriterT w m) where
(<*>) :: WriterT w m (a -> b) -> WriterT w m a -> WriterT w m b
mf <*> ma = WriterT $ h <$> runWriterT mf <*> runWriterT ma
where
h (f, w1) (a, w2) = (f a, w1 <> w2)
대충 이런 느낌이에요.여기서 국부 정의h
의 무적분을 어떻게 씁니까?이를 위해서는 일반화
h
부터 고려해야 한다.bimap
h
일반화하면 아래가 이렇게 되겠죠.h :: (a1 -> a2 -> a3) -> (b1 -> b2 -> b3) -> (a1, b1) -> (a2, b2) -> (a3, b3)
h f g (a1, b1) (a2, b2) = (f a1 a2, g b1 b2)
원조의 각 요소에 서로 다른 함수를 응용했기 때문에bimap
사용할 수 있을 것 같다.h' :: (a1 -> a2) -> (b1 -> b2) -> (a1, b1) -> (a2, b2)
h' f g = bimap f g
하지만 이것은 예상대로 활동할 수 없다.(a2->a3, b2->b3)
처럼 결과 유형의 원조 내부에 함수가 있기 때문이다.-- a2 = a2 -> a3, b2 = b2 -> b3 として型を変形
h' :: (a1 -> a2 -> a3) -> (b1 -> b2 -> b3) -> (a1, b1) -> (a2 -> a3, b2 -> b3)
h' f g = bimap f g
즉 (a2 -> a3, b2 -> b3) -> (a2, b2) -> (a3, b3)
의 함수를 찾으면 함수h
는 점 없이 쓸 수 있다는 것이다.h'' :: (a -> b) -> (c -> d) -> (a, c) -> (b, d)
h'' = undefined
대답은 스스로 생각해 보세요 (1시간 정도 걸렸어요)
Reference
이 문제에 관하여(비맵으로 놀아요.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/wado/articles/95bc345524ce01텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)