귀하의 Foo
유형은 Atkey는 원래 parameterised monad라는 내용의 예이고, 다른 사람은 (틀림없이 잘못) 지금 색인 모나드를 호출합니다.
인덱싱 된 모나드는 유형의 방향 그래프를 통해 경로를 설명하는 두 개의 인덱스가있는 모나드 형 오브젝트입니다. 인덱싱 된 모나드 계산을 시퀀싱하려면 두 계산의 인덱스가 도미노처럼 정렬되어 있어야합니다. 당신이 y
에서 z
에 도착하는 x
에서 y
의 경로를 설명하는 인덱스 모나드 및 방법이있는 경우
class IFunctor f where
imap :: (a -> b) -> f x y a -> f x y b
class IFunctor f => IApplicative f where
ipure :: a -> f x x a
(<**>) :: f x y (a -> b) -> f y z a -> f x z b
class IApplicative m => IMonad m where
(>>>=) :: m x y a -> (a -> m y z b) -> m x z b
는 인덱스 바인드 >>>=
당신에게 x
에서 z
로 이동 더 큰 계산을 제공 할 것입니다.
또한 ipure
은 f x x a
을 반환합니다. ipure
에 의해 반환 된 값은 유형의 유향 그래프를 통해 어떠한 단계도 수행하지 않습니다. 유형 수준 id
과 같습니다.
색인 모나드의 간단한 예는, 어떤 당신이 당신의 질문에 언급하기 i
에서 o
에 대한 인수의 형식을 변환하는 인덱스 상태 모나드 newtype IState i o a = IState (i -> (o, a))
입니다. 첫 번째 출력 유형이 두 번째 입력 유형과 일치하는 경우에만 상태 저장 연산을 시퀀싱 할 수 있습니다. 실제 질문에 이제
newtype IState i o a = IState { runIState :: i -> (o, a) }
instance IFunctor IState where
imap f s = IState $ \i ->
let (o, x) = runIState s i
in (o, f x)
instance IApplicative IState where
ipure x = IState $ \s -> (s, x)
sf <**> sx = IState $ \i ->
let (s, f) = runIState sf i
(o, x) = runIState sx s
in (o, f x)
instance IMonad IState where
s >>>= f = IState $ \i ->
let (t, x) = runIState s i
in runIState (f x) t
. domino-esque 시퀀싱을 사용하는
IMonad
은 유형 수준 환경을 변환하는 계산을위한 좋은 추상화입니다. 첫 번째 계산이 환경을 두 번째 상태에 알맞은 상태로 유지할 것으로 기대합니다.
Foo
에
IMonad
의 인스턴스를 작성하겠습니다.
Woo s a
유형이 Writer
모나드의 예인 (a, Maybe s)
과 같은 모양이라는 점부터 알아 보겠습니다. 우리가 나중에 Monad (Woo s)
에 대한 인스턴스를 필요로하기 때문에 나는 이것을 언급하고 나 자신을 쓰기에는 너무 게으른 편이다.
type Woo s a = Writer (First s) a
내가 Maybe
모노 이드의 내 선호하는 맛으로 First
을 골랐다하지만 Woo
를 사용하려면 어떻게 정확히 알 수 없습니다. Last
을 선호 할 수도 있습니다.
또한 Writer
이 Traversable
의 인스턴스라는 사실을 곧 사용할 예정입니다. 실제로 Writer
은 그 이상으로 이동하기가 쉽습니다. 정확히 하나의 a
이 포함되어 있기 때문에 어떤 결과도 함께 제거 할 필요가 없습니다. 즉, 효과가있는 f
에 대해 Functor
제약 조건 만 있으면됩니다.
-- cf. traverse :: Applicative f => (a -> f b) -> t a -> f (t b)
traverseW :: Functor f => (a -> f b) -> Writer w a -> f (Writer w b)
traverseW f m = let (x, w) = runWriter m
in fmap (\x -> writer (x, w)) (f x)
사업에 착수합시다.
Foo s
은 IFunctor
입니다. 이 인스턴스는 Writer s
의 functor-ness를 사용합니다 : 우리는 stateful 계산을하고 fmap
Writer
모나드 함수를 사용합니다.
newtype Foo (s :: *) (env :: [(Symbol,*)]) (env' :: [(Symbol,*)]) (a :: *) =
Foo { runFoo :: s -> Sing env -> (Woo s a, Sing env') }
instance IFunctor (Foo s) where
imap f foo = Foo $ \s env ->
let (woo, env') = runFoo foo s env
in (fmap f woo, env')
우리는 또한 나중에 traverseW
와 함께 사용, 일반 Functor
Foo
를 확인해야합니다.
instance Functor (Foo s x y) where
fmap = imap
Foo s
는 IApplicative
입니다. Woo
을 함께 분쇄하려면 Writer s
의 Applicative
인스턴스를 사용해야합니다. 이 부분은 Monoid s
제약 조건에서 비롯됩니다.
instance IApplicative (Foo s) where
ipure x = Foo $ \s env -> (pure x, env)
foo <**> bar = Foo $ \s env ->
let (woof, env') = runFoo foo s env
(woox, env'') = runFoo bar s env'
in (woof <*> woox, env'')
Foo s
는 IMonad
입니다. 놀람 놀람, 우리는 Writer s
의 Monad
인스턴스에 위임하는 것을 끝낸다. 작가 안의 중간에 a
을 먹이기 위해 traverseW
을 교묘히 사용하는 것은 클레이슬러 화살표 f
에 유의하십시오.
instance IMonad (Foo s) where
foo >>>= f = Foo $ \s env ->
let (woo, env') = runFoo foo s env
(woowoo, env'') = runFoo (traverseW f woo) s env'
in (join woowoo, env'')
부록 :이 그림에서 빠진 것은 변압기입니다.
type Foo s env env' = ReaderT s (IStateT (Sing env) (Sing env') (WriterT (First s) Identity))
을하지만 인덱스 모나드는 변압기에 대해 사람들에게 꼭 이야기를하지 않습니다 본능은 당신이 모나드 변압기 스택으로 Foo
을 표현 할 수 있어야한다고 하더군요. >>>=
의 타입은 스택의 모든 인덱스 된 모나드가 같은 방식으로 인덱스를 조작해야 할 필요가 있습니다. 이것은 아마도 원하는 것이 아닙니다. 인덱싱 된 모나드는 일반 모나드와도 잘 어울리지 않습니다.
이 모든 것은 인덱스 된 모나드 변환기가 McBride-style indexing scheme으로 조금 더 멋지게 재생된다는 것을 말합니다. 맥브라이드의 IMonad
은 다음과 같습니다
type f ~> g = forall x. f x -> g x
class IMonad m where
ireturn :: a ~> m a
(=<?) :: (a ~> m b) -> (m a ~> m b)
그리고 모나드 변압기는 다음과 같이 보일 것이다 :
class IMonadTrans t where
ilift :: IMonad m => m a ~> t m a
나는 이것이 또 다른 좋은 대답이라고 생각한다; 그것은 모두'Foo' 유형에 대한 OP의 계획에 달려 있습니다. 호기심에서 parAp :: f w x (a -> b) -> f y z a -> f (w, y) (x, z) b'와 병렬 처리 된 색인 어플 리케이션으로 놀아 보는 사람은 누구인가? – rampion
'parAp'는'i ~ '[w, x]'와'j ~'를 설정하면'fi (a -> b) -> fja -> f (i ++ j) , z]'. 이 유형은 [Orchard의 색인 된 모나드 버전] (http://www.cl.cam.ac.uk/~dao29/ixmonad/ixmonad-fita14.pdf)의 경우 'ap'와 유사합니다. 그는 유형 수준의 모노로이드를 사용하여 지수에 합류했습니다. –