모나드
모나드 구성
또한 모나드가 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
)를 .
펑터
모나드와 마찬가지로 펑 터는 다음 세 가지 항목으로 정의 할 수 있습니다.
- 무제한의 단일 유형 변수에 대해 매개 변수화 된 데이터 유형.
두 가지 작업 :
pure
functor에 순수한 가치를 담습니다. 이것은 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 될 수 가정 할 수 있습니다 나는 자유 모나드를 통해 표현 될 수없는 제안 보았다 모나드이다. 거의 다른 무엇이든 할 수 있습니다 .