문제

간단한 나무 구조가 있습니다.

data Tree a = Leaf | Node a (Tree a) (Tree a)

그리고 a 접을 수 있습니다 구현:

import qualified Data.Foldable as F

instance F.Foldable Tree where
  foldMap f Leaf         = mempty
  foldMap f (Node x l r) = F.foldMap f l `mappend`
                           f x           `mappend`
                           F.foldMap f r

그리고 그것은 구현이 없어도 작동합니다. Monoid 그리고 나는 어느 것도 사용할 수 없습니다 mappend ...도 아니다 mempty 내 코드에서. 그렇다면 어떻게해야합니까? Foldable 구현 작업?

도움이 되었습니까?

해결책

유형을 검사하는 경우 foldMap

class Foldable f where
  foldMap :: Monoid m => (a -> m) -> f a -> m

당신은 그것이 결합되지 않은 유형을 가지고 있음을 알 수 있습니다 m. 일반적으로 이것이 발생하면 의미가 있습니다 m 할 수 있습니다 아무것, 그러나 여기서도 제한됩니다 m ~와 함께 Monoid m. 그게 거기입니다 Monoid 에서 오는.

우리가 가지고 있지 않다면 Monoid 인스턴스는 "무엇이든 될 수있는 값"을 반환하는 함수를 정의하기가 매우 어렵습니다. 당신이 그것을 시도하면, 당신은 거의 불가능하다는 것을 알게 될 것입니다 ( "속임수"없이).

impossible :: Int -> b -- no constraints on `b` at all!
impossible i = ...?

하지만 우리 가이 유형에 대해 조금 알고 있다면 매우 쉽습니다.

veryPossible  :: Num b => Int -> b
veryPossible  i = fromIntegral i
-- or
veryPossible2 i = fromIntegral (i * i) + fromIntegral i

또 다른 예로서, 표현의 유형을 고려하십시오

expr m = mconcat [m <> m <> mempty, mempty <> m]

이 표현식은 알려지지 않은 값에 따라 구축되므로 m 그리고 사용 의 기능 Monoid 클래스 또는 파생 상품은 유형을 반영합니다. 가장 일반적인 유형 expr ~이다

expr :: Monoid m => m -> m

다시 여기, m 자유 형식 변수입니다 약간 Monoid.


이유 foldMap 사용할 수 있습니다 Monoid 기능은 m 유형의 서명은 될 수 있습니다. 그곳에 제약을함으로써 우리는 그것들을 조작 할 수있는 더 많은 힘을 얻습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top