Arrows
은 범주별로 일반화되어 있으므로 Category
typeclass입니다.
class Category f where
(.) :: f a b -> f b c -> f a c
id :: f a a
Arrow
typeclass 정의는 수퍼 클래스 Category
있다. (haskell 감각의) 카테고리는 함수를 일반화 (당신이 그것들을 작성할 수는 있지만 적용 할 수는 없다)하며 따라서 "계산의 모델"이다. Arrow
은 튜플을 사용하기위한 추가 구조로 Category
을 제공합니다. 따라서 Category
은 하스켈의 함수 공간에 대해 어떤 것을 비 춥니 다. Arrow
은 제품 유형에 관한 내용으로 확장합니다.
모든 Monad
은 "클레이 슬 카테고리 (Kleisli Category)"라고 불리는 것을 발생시키고이 구성은 ArrowApply
의 인스턴스를 제공합니다. ArrowApply
에서 Monad
을 만들면 완전한 원이 행동을 바꾸지 않기 때문에 어떤 깊은 의미에서 Monad
과 ArrowApply
은 같은 것입니다.
newtype Kleisli m a b = Kleisli { runKleisli :: a -> m b }
instance Monad m => Category (Kleisli m) where
id = Kleisli return
(Kleisli f) . (Kleisli g) = Kleisli (\b -> g b >>= f)
instance Monad m => Arrow (Kleisli m) where
arr f = Kleisli (return . f)
first (Kleisli f) = Kleisli (\ ~(b,d) -> f b >>= \c -> return (c,d))
second (Kleisli f) = Kleisli (\ ~(d,b) -> f b >>= \c -> return (d,c))
사실 모든 Arrow
는 Category
슈퍼 클래스에 추가 (종류 권리를 얻을 보편적으로 정량화)는 Applicative
상승을 제공, 그리고 적절한 Category
및 Applicative
의 조합이 Arrow
을 재구성하기에 충분하다 생각합니다.
이러한 구조는 깊이 연결되어 있습니다.
경고 : wishy-washy 해설 전방. 사고의 Functor
/Applicative
/Monad
방식과 사고의 Category
/Arrow
방법 사이에 하나의 중앙 차이점은 Functor
와 그 동류가 객체 (하스켈 타입)의 수준에서 일반화는 동안/Arrow
Category
가의 generelazation 있다는 것입니다 도형 (하스켈의 함수)의 개념. 제 생각에 일반화 된 레벨 인 의 모폴로지에서 생각하는 것은 일반화 된 레벨 인 오브젝트에서 생각하는 것보다 높은 수준의 추상화가 필요하다는 것입니다. 때로는 좋은 일이지만 그렇지 않은 경우도 있습니다. 반면에, Arrows
에는 범주 적 근거가 있고 수학에서 아무도 Applicative
이 재미 있다고 생각하지만 은 일반적으로 Arrow
보다 더 잘 이해됩니다.
기본적으로 당신이 생각할 수있는 "카테고리 < 화살표 < ArrowApply"와 "은 Functor < 실용적 < 모나드"등이 "종류 ~은 Functor", "화살표 ~ 실용적"와 "ArrowApply ~ 모나드".
더 아래 콘크리트 다음 "이중"또는 "공동 건설을 얻기 위해 범주 구조에서 (여기 morphisms을 의미) 하나는 종종"화살표 "의 방향을 반대로 할 수 있습니다 다른 구조 계산을 모델링 할로 ". 모나드가
class Functor m => Monad m where
return :: a -> m a
join :: m (m a) -> m a
로 정의한다면, 는 다음 comonad이
class Functor m => Comonad m where
extract :: m a -> a -- this is co-return
duplicate :: m a -> m (m a) -- this is co-join
이다 (좋아, 나는 하스켈 일을 정의하는 방법 아니라는 것을 알고 있지만,
ma >>= f = join $ fmap f ma
및
join x = x >>= id
그래서 그냥뿐만 아니라 수)
이 문제는 꽤 일반적이기도합니다. Comonad
은 셀룰러 오토 데이터의 기본적인 기본 구조입니다. completness, 나는 "확장 가능 펑"에 대한 펑과 Comonad
사이에 클래스의 에드워드 Kmett의 Control.Comonad
둔다는 duplicate
당신은 또한 그것은 모든 Monad
들도
"확장 가능한"것으로 밝혀
extend :: (m a -> b) -> m a -> m b -- Looks familiar? this is just the dual of >>=
extend f = fmap f . duplicate
--this is enough
duplicate = extend id
을 정의 할 수 있기 때문에 지적한다
monadDuplicate :: Monad m => m a -> m (m a)
monadDuplicate = return
모든 Comonads
이
comonadJoin :: Comonad m => m (m a) -> m a
comonadJoin = extract
그래서 "결합 가능한"동안 이 구조들은 매우 가깝다.
Monad vs. Arrows 페이지는 응용 펑터 (일명 숙어)를 비교 한 종이에 대한 링크입니다. –
적용 가능한 펑터는 계산할 수있는 계산에 능숙합니다! 실제로 그들은 모나드보다 더 잘 구성됩니다 (두 개의 응용 펑터의 구성은 모나드에 대해 적용되지 않는 응용 펑터입니다). – ehird