2022. 11. 21. 00:00ㆍFunctional Programming/Category Theory

모나드는 Flatten이 되는 Functor 이다.
지금까지 우리가 여러가지 개념을 배웠고 그러면서 이전시간 까지 Functor 에 대해 배웠다
그리고 Functor 중 몇몇을 예로 들어 설명하였다.
Monad 는 Flatten 이 되는 Functor 이다.
이것이 monad 의 개념이다.
우리가 Flatten 이 무엇이지 Functor 가 무엇인지 모른다면 이 개념처럼 모호한 개념이 없다.
Flatten
List<List<string>> ==> Flatten ==> List<string>
Functor
- 사용자가 맵핑 할 수있는 데이터 타입
- 내부의 값에 함수를 적용하는 인터페이스가 있는 컨테이너
- “mappable” 한 무언가
물론 그 안에는 더 많은 개념이 있다.
하지만 기본적인 정의는 위와 같이 표현할 수 있다.
Flatten 은 말로 표현하는 것보다 sampe 이 더 이해하기 쉬울것이다.
결과적으로 unwrapping 하는 것이므로 그렇게 이해하면 된다.
https://yogingang.tistory.com/375
Category : The Essence of Composition (Category: Composition 의 본질)
참고 : https://bartoszmilewski.com/2014/11/04/category-the-essence-of-composition/ Category 는 개체와 개체 사이를 이동하는 화살표로 구성된다. Category 의 본질은 Composition 이다. 객체 A 에서 B 로의 화살표와 객체 B
yogingang.tistory.com
https://yogingang.tistory.com/384
Functor
참고 : https://bartoszmilewski.com/2015/01/20/functors/ functor는 두 범주 간의 매핑이다. 펑터는 객체뿐만 아니라 객체 간의 기능(모피즘이라고 함)도 매핑한다. 예를 들어, 펑터 F는 카테고리 C와 D 사이의 매
yogingang.tistory.com
Monad 는 다음과 같은 구현이 필요하다
bind :: m a -> (a -> m b) -> m b
return :: a -> m a
Bind 는 FlatMap 이라고도 하고 C# 에서는 SelectMany 라고도 한다.
Bind 는 M<A> 값이 들어왔을때 이것을 fmap 하는 과정중에
M<M<A>> 형태로 처리하게 되는 문제를 해결하기 위한 것이다.
Flat 이란 저 M<M<A>> 를 M<A> 형태로 unwrap 해준다. (flat)
List<List<string>> 형태를 SelectMany 를 통해 List<string> 형태로 바꾸는것과 동일 한다.
어쨌든 Monad 는 저 bind 와 return 이 필요하다.
Return 은 a 라는 값을 받아 M<A> 형태로 Monad 즉 Container 안에 집어 넣어 return 하는 함수 이다.
C# Nullable Monad ( Maybe ?? )
이제 C# 에서 사용하고 있는 Monad 와 가장 비슷한 내용을 구현해 보겠다.
실제 C# 에서 언어적 한계로 인해 Haskell 같이 추상화된 Monad를 사용하기는 어렵다.
아래 구현을 보자
int? : int 이거나 null 을 갖을 수 있는 c# 형 Maybe Monad (완전히 같지는 않다.)
이것은 실제 Nullable<int> 와 일치 한다.
int? f() { return 5; }
int? g() { return 7; }
int? h() { return 9; }
int? z = f().Bind(fval => g().Bind(gval => h().Bind(hval =>
new int?(fval + gval + hval))));
아래는 Bind 에 대한 Extension Method 이다.
public static B? Bind<A, B>(this A? a, Func<A, B?> f)
where B : struct
where A : struct
{
return a.HasValue ? f(a.Value) : null;
}
Nullable<A> 가 값을 가지면 (HasValue) Function f 를 실행하고 그렇지 않다면 null 을 return 한다.
실제 위의 코드를 실행하면 z = 21 이라는 값이 나온다.
만약 f , g, h 중 하나라도 null 을 갖는다면 Bind 함수에 의해 z = null 을 return 받게 된다.
Bind 함수를 보면
A? a 를 m a
Func<A, B?> 를 (a -> m b)
B? 를 m b
라고 볼 수 있다. 이를 다시 표현해 보면
A? a , Func<A,B?> f return B?
m a -> (a -> m b) --> m b
m a -> (a -> m b) -> m b
위와 같이 해석 할 수 있게 된다.
즉 Nullable 의 Bind 는 Monad 의 bind 규칙과 일치한다.
사실 C# 에서도 ReaderMonad 니 WriterMonad 니 하는 것들을 구현 가능하다
F# 과 비슷하게 Option, Lift 등등을 구현할 수도 있다.
하지만 이러한 것들은 언어적 한계점으로 인해 많이 부족한 점을 보인다.
혹자는 https://github.com/louthy/language-ext 를 이용하여
이러한 부족한 점을 채우는 방법이 있다고 하지만
실상 그와 같은 것을 쓰게 된다면 ..
결국에는 F# 으로 Library 를 만들어 활용(?) 하는 것이 더욱 나을 수 있다.
일단 Functional Programming 에 대한 내용은 여기 까지다.
좀 많은 시간을 들여서 Category Theory 부터 달려왔었다.
결과적으로 모든것을 이해했던것은 아니지만 Functional Programming 에서 사용하는
많은 Pattern 들에 대해 알아보게된 계기가 되었다고 생각한다.
향후에 OOP 안에서 Function 관련된 부분에 이러한 Compose , Bind, Flat 같은 개념들을 사용하고
c# 에서 Monad 를 활용하는 가장 좋은 방법을 알게 된다면
다시 한번 이곳에서 이부분에 대한 이야기를 하게 될것 같다.
Free Monad 로 DSL (Flow) 을 만들고
CoPilot 같은 AI 도구로 단위 Function 을 생성하고
단위 Funtion 과 단위 Function 을 Compose 하여 원하는 수준의 개발을 할 수 있게되면 그때 다시 이야기 해보겠다.
관련영상
'Functional Programming > Category Theory' 카테고리의 다른 글
Contravariant Functor, Profunctor (0) | 2022.11.14 |
---|---|
ApplicativeFunctor, BiFunctor (0) | 2022.11.07 |
Functor (0) | 2022.10.31 |
Product and CoProduct (0) | 2022.10.24 |
Kleisli Catogories (0) | 2022.10.17 |