모나드
모나드 구성
또한 모나드가 pure되고bind 세 개의 모나드의 법을 준수해야합니다.
이제 C #에서 모나드를 모델링하는 한 가지 방법은 인터페이스를 구성하는 것입니다.
interface Monad<M> {
M<T> pure(T v);
M<B> bind(M<A> mv, Func<A, M<B>> f);
}
(참고 : 일을 간략하고 표현력있게 유지하기 위해이 답변 전체에서 코드를 자유롭게 사용할 것입니다.)
이제 구체적인 구현을 구현하여 구체적인 데이터 기프에 대한 모나드를 구현할 수 있습니다 Monad<M>. 예를 들어 다음과 같은 모나드를 구현할 수 있습니다 IEnumerable.
class IEnumerableM implements Monad<IEnumerable> {
IEnumerable<T> pure(T v) {
return (new List<T>(){v}).AsReadOnly();
}
IEnumerable<B> bind(IEnumerable<A> mv, Func<A, IEnumerable<B>> f) {
;; equivalent to mv.SelectMany(f)
return (from a in mv
from b in f(a)
select b);
}
}
LINQ 구문과 모나드 간의 관계를 호출하기 위해 의도적으로 LINQ 구문을 사용하고 있습니다. 그러나 LINQ 쿼리를에 대한 호출로 바꿀 수 SelectMany있습니다.
이제 모나드를 정의 할 수 IObservable있습니까? 그렇게 보일 것입니다 :
class IObservableM implements Monad<IObservable> {
IObservable<T> pure(T v){
Observable.Return(v);
}
IObservable<B> bind(IObservable<A> mv, Func<A, IObservable<B>> f){
mv.SelectMany(f);
}
}
모나드가 있는지 확인하려면 모나드 법칙을 증명해야합니다. 이것은 사소한 일이 아니며 (Rx.NET이 사양만으로도 입증 될 수 있는지 여부를 알기에 충분하지는 않습니다) 유망한 시작입니다. 이 논의의 나머지 부분을 용이하게하기 위해,이 경우 모나드 법칙이 유지한다고 가정 해 봅시다.
무료 모나드
단수의 "무료 모나드"는 없습니다. 오히려, 무료 모나드는 펑터로 구성된 모나드 클래스입니다. , 펑터 주어 즉 F, 우리의 모나드 파생 자동으로 할 수 있습니다 F(즉,의 무료 모나드를F )를 .
펑터
모나드와 마찬가지로 펑 터는 다음 세 가지 항목으로 정의 할 수 있습니다.
- 무제한의 단일 유형 변수에 대해 매개 변수화 된 데이터 유형.
두 가지 작업 :
purefunctor에 순수한 가치를 담습니다. 이것은 pure모나드와 유사합니다 . 실제로 모나드이기도 한 펑터의 경우 두 개가 동일해야합니다.
fmap주어진 함수를 통해 입력 값을 출력의 새 값에 매핑합니다. 서명은 다음과 같습니다.
F<B> fmap(Func<A, B> f, F<A> fv)
모나드와 마찬가지로 펑 터는 펑터 법을 준수해야합니다.
모나드와 유사하게 다음 인터페이스를 통해 펑터를 모델링 할 수 있습니다.
interface Functor<F> {
F<T> pure(T v);
F<B> fmap(Func<A, B> f, F<A> fv);
}
이제 모나드는 functors의 하위 클래스이므로 Monad약간 리팩터링 할 수도 있습니다 .
interface Monad<M> extends Functor<M> {
M<T> join(M<M<T>> mmv) {
Func<T, T> identity = (x => x);
return mmv.bind(x => x); // identity function
}
M<B> bind(M<A> mv, Func<A, M<B>> f) {
join(fmap(f, mv));
}
}
여기에 추가로 방법을 추가 한 join, 모두의 기본 구현 제공 join및 bind. 그러나 이들은 원형 정의입니다. 따라서 적어도 하나 이상을 재정의해야합니다. 또한 pure이제는에서 상속됩니다 Functor.
IObservable 그리고 무료 모나드
이제 모나드에 대해 모나드를 정의 IObservable했으므로 모나드는 functors의 하위 클래스이므로에 대한 functor 인스턴스를 정의 할 수 있어야합니다 IObservable. 여기 하나의 정의가 있습니다 :
class IObservableF implements Functor<IObservable> {
IObservable<T> pure(T v) {
return Observable.Return(v);
}
IObservable<B> fmap(Func<A, B> f, IObservable<A> fv){
return fv.Select(f);
}
}
에 대한 functor가 정의 IObservable되었으므로 해당 functor에서 무료 모나드를 생성 할 수 있습니다. 이것이 바로 IObservable무료 모나드와 어떻게 관련이 있는지 , 즉 우리는에서 무료 모나드를 구성 할 수 있다는 것입니다 IObservable.
Cont(가) 단지, 하나는 아마 FRP 될 수 가정 할 수 있습니다 나는 자유 모나드를 통해 표현 될 수없는 제안 보았다 모나드이다. 거의 다른 무엇이든 할 수 있습니다 .