foldr
/foldl
의 결과가 동일하면 주어진 접기 기능을 연관 적으로 제한하지 않아야합니까? foldr
/foldl
의 결과가 같은 목록에서 다른 예가 있습니까?
예. 비 연관 함수 (빼기 (-)
과 같이)를 전달하면 절대 다른 결과를 얻습니다. 그리고 여러분이 올바르게 지적한 바처럼 과 같은 것에 해당하는 Monoid
인스턴스가 없습니다.
그러나 의도적으로 설계된 동작입니다. Foldable
인스턴스에는 foldr
과 foldl
이 연관 기능을 사용해야한다는 제한이 없습니다. 뺄셈과 같은 것으로 접을 수있는 상황이 있습니다. Foldable f
의 인스턴스는 f
이 수행 할 수있는 것을 제한하는 데 더 관심이 있습니다. 특히 법은 다음과 같습니다
foldr f z t = appEndo (foldMap (Endo . f) t) z
foldl f z t = appEndo (getDual (foldMap (Dual . Endo . flip f) t)) z
fold = foldMap id
-- if f is a Functor
foldMap f = fold . fmap f
foldMap f . fmap g = foldMap (f . g)
기본적으로
foldr
가
newtype Endo a = Endo (a -> a)
자기 사상의 모노 이드와 영리한 무언가를 당신이 소스에서 볼 수
:
-- | Right-associative fold of a structure.
--
-- @'foldr' f z = 'Prelude.foldr' f z . 'toList'@
foldr :: (a -> b -> b) -> b -> t a -> b
foldr f z t = appEndo (foldMap (Endo #. f) t) z
가능성이 비 monoidal 밖으로 배 monoidal 구축 f
및 z
.
그래서 궁극적으로 "모노oid는 왜 요구 사항이 아닌가?"라는 질문에 대한 대답입니다. 매우 실용적이며, 결과적으로 필요하지 않기 때문에 매우 지루하다. "
자세한 내용은 모든 것을 시작한 문서 Applicative Programming with Effects을 참조하십시오.
출처
2016-06-22 16:58:31
hao
'foldr' 및'foldl'의 첫 번째 함수의 유형을 살펴보십시오. 모노로이드는 거기에 맞지 않습니다. – pdexter
@pdexter Nah, 모든 것이 "일종의 목록"으로 취급되기 때문에 Monoid가 표준 폴드에 실제로 의미가있는 유일한 것입니다. 유형이 더 복잡한 구조로 취급되는 경우, 이름에서 "왼쪽"과 "오른쪽"은 의미가 없습니다. 리스트가 아닌 다른 것들로 넘어 가고 싶다면 더 복잡한 대수를 제공해야합니다. –
기능 구성 *은 다음과 같습니다 : 연관 :'foldr :: (a -> b -> b) -> b -> ta -> b','foldr (c :: (a -> b -> b) b -> ta -> b', **'c (x :: a) :: b -> b' **이므로'cx1','cx2', ...,'c 우리가 좋아하는 순서대로 xn'을 사용한다. 왜냐하면/IOW endofunctions은 monoid 인'Endo b'를 모두 만들어 내기 때문이다. 예를 들면. '(x :) == ([x] ++)'즉,'c'를 적절한 f와'cx '로''cx = (fx <>)'라고 표현할 수있다. c y ~ = f x <> f y'. (또는 그와 비슷한 것). –