Functor / Functor / Applicative / Monad가 아닌 좋은 예?


209

타입 클래스 X가 무엇인지 누군가에게 설명하면서 정확히 X 인 데이터 구조의 좋은 예를 찾기 위해 고심하고 있습니다.

따라서 다음에 대한 예를 요청합니다.

  • Functor가 아닌 타입 생성자.
  • Functor이지만 형식이 아닌 형식 생성자입니다.
  • Applicative이지만 Monad가 아닌 형식 생성자입니다.
  • Monad 인 타입 생성자.

나는 모나드에 대한 많은 예가 있다고 생각하지만, 이전 예와 관련이있는 모나드의 좋은 예가 그림을 완성 할 수 있습니다.

특정 유형 클래스에 속하는 중요한 측면에서만 다른 서로 유사한 예제를 찾습니다.

이 계층 구조의 어딘가에 Arrow의 예제를 적용 할 수 있다면 (응용 프로그램과 Monad 사이입니까?)


4
적합 하지 않은 형식 생성자 ( * -> *) 를 만들 수 있습니까? fmap
Owen

1
오웬, 제 생각 a -> String에는 펑터가 아닌 것 같습니다 .
Rotsor

3
@Rotsor @Owen a -> String은 수학 함수이지만 하스켈은 아닙니다 Functor.
J. Abrahamson

@제이. 그때 아브라함 손은 어떤 의미에서 수학 펑터입니까? 화살표가 반전 된 카테고리에 대해 이야기하고 있습니까?
Rotsor

3
모르는 사람들을 위해, 반 변형 펑 터는 다음 유형의 fmap (a -> b) -> f b -> f a
을가집니다

답변:


100

Functor가 아닌 타입 생성자 :

newtype T a = T (a -> Int)

반공 변 펑터를 (공변량) 펑터로 만들 수는 없습니다. 쓰기를 시도 fmap하면 실패합니다. 반 변형 functor 버전은 반대로되어 있습니다.

fmap      :: Functor f       => (a -> b) -> f a -> f b
contramap :: Contravariant f => (a -> b) -> f b -> f a

functor이지만 형식이 아닌 형식 생성자 :

좋은 예가 없습니다. 이 Const있지만 이상적으로 는 비모 노이드가 아닌 콘크리트를 원하며 전혀 생각할 수 없습니다. 모든 유형은 기본적으로 숫자, 열거 형, 곱, 합계 또는 함수입니다. 당신은 pigworker 아래 참조 나는 여부에 대해 동의하지 수 Data.VoidA는 Monoid;

instance Monoid Data.Void where
    mempty = undefined
    mappend _ _ = undefined
    mconcat _ = undefined

이후로는 _|_하스켈 법적 값이고, 사실의 유일한 법적 값 Data.Void이는 모노 이드 규칙을 준수합니다. unsafeCoerce프로그램이 더 이상 unsafe함수 를 사용하자마자 Haskell 의미를 위반하지 않도록 보장되지 않기 때문에 관련이 있는지 확실 하지 않습니다 .

하단에있는 기사 ( 링크 ) 또는 안전하지 않은 기능 ( 링크 )에 대해서는 Haskell Wiki를 참조하십시오 .

다양한 확장 기능을 가진 Agda 또는 Haskell과 같은 더 풍부한 유형 시스템을 사용하여 이러한 유형 생성자를 만들 수 있는지 궁금합니다.

응용 프로그램이지만 Monad가 아닌 형식 생성자 :

newtype T a = T {multidimensional array of a}

다음과 같은 방법으로 Applicative를 만들 수 있습니다.

mkarray [(+10), (+100), id] <*> mkarray [1, 2]
  == mkarray [[11, 101, 1], [12, 102, 2]]

그러나 모나드로 만들면 치수 불일치가 발생할 수 있습니다. 나는 이와 같은 예가 실제로 드문 것으로 생각됩니다.

Monad 인 타입 생성자 :

[]

화살표 정보 :

이 계층 구조에서 화살표가 어디에 있는지 묻는 것은 어떤 종류의 "빨간색"인지 묻는 것과 같습니다. 종류의 불일치에 유의하십시오.

Functor :: * -> *
Applicative :: * -> *
Monad :: * -> *

그러나,

Arrow :: * -> * -> *

3
좋은 목록! Either a이해하기 쉽기 때문에 마지막 사례의 예로 더 간단한 것을 사용하는 것이 좋습니다 .
fuz

6
Applicative이지만 Monad가 아닌 형식 생성자를 찾고 있다면 매우 일반적인 예는 다음과 같습니다 ZipList.
John L

23
_|_*의 모든 유형에 거주하지만 요점은 Void거꾸로 구부려서 하나를 만들거나 그 가치를 파괴해야한다는 것입니다. 이것이 Enum, Monoid 등의 인스턴스가 아닌 이유입니다. 이미 가지고있는 경우, 함께 묶어 줘서 행복 Semigroup하지만 ()를 제공 하지만 기꺼이 mempty유형 값을 명시 적으로 구성하는 도구는 없습니다 Void. void. 총을 싣고 발을 향하게하고 방아쇠를 직접 당겨야합니다.
Edward KMETT

2
놀랍게도, 나는 당신의 코 펀터 개념이 잘못되었다고 생각합니다. functor의 이중은 functor입니다. 입력 출력을 모두 뒤집고 같은 결과를 얻기 때문입니다. 당신이 찾고있는 개념은 아마도 "반 변량 functor"일 것입니다.
벤 밀우드

1
@AlexVong : "Deprecated"-> 사람들이 다른 패키지를 사용하고 있습니다. "Functor의 듀얼"이 아닌 "Contravariant Functor"에 대해 이야기하면서 혼란을 드려 죄송합니다. 어떤 맥락에서 나는 "공진기 (cofunctor)"가 "반 변형 펑터 (contravariant functors)"를 지칭하는 데 사용되는 것을 보았습니다.
Dietrich Epp

87

내 스타일이 휴대 전화에 의해 좁아 질 수 있지만 여기로갑니다.

newtype Not x = Kill {kill :: x -> Void}

Functor가 될 수 없습니다. 만약 그렇다면, 우리는

kill (fmap (const ()) (Kill id)) () :: Void

달은 녹색 치즈로 만들어졌습니다.

그 동안에

newtype Dead x = Oops {oops :: Void}

functor입니다

instance Functor Dead where
  fmap f (Oops corpse) = Oops corpse

하지만 적용 할 수는 없습니다.

oops (pure ()) :: Void

그리고 초록색은 문 치즈로 만들어 졌을 것입니다.

(추가 메모 : Void에서와 같이 Data.Void빈 데이터 유형입니다. undefinedMonoid임을 증명하는 데 사용하려는 경우 그렇지 unsafeCoerce않은 것을 증명하는 데 사용 합니다.)

즐겁게

newtype Boo x = Boo {boo :: Bool}

예를 들어 Dijkstra는 다양한 방식으로 적용 할 수 있습니다.

instance Applicative Boo where
  pure _ = Boo True
  Boo b1 <*> Boo b2 = Boo (b1 == b2)

그러나 모나드는 될 수 없습니다. 왜 그렇지 않은지 보려면, 수익률이 지속적으로 Boo True또는 이어야 Boo False하므로

join . return == id

개최 할 수 없습니다.

오 예, 거의 잊었습니다

newtype Thud x = The {only :: ()}

Monad입니다. 자신의 롤.

잡을 비행기 ...


8
공허가 비어 있습니다! 도덕적으로, 어쨌든.
pigworker

9
Void는 생성자가 0 인 유형입니다. 이 없기 때문에 단일체가 아닙니다 mempty.
Rotsor

6
찾으시는 주소가 없습니다? 얼마나 무례! 안타깝게도 unsafeCoerce (unsafeCoerce () <*> undefined)는 ()가 아니므로 실제로는 법을 위반하는 관찰이 있습니다.
pigworker

5
정확히 한 종류의 정의되지 않은 것을 견딜 수있는 일반적인 의미론에서는 매우 옳습니다. 물론 다른 의미론도 있습니다. 공허는 전체 조각에서 서브 모노 이드로 제한되지 않습니다. 또한 실패 모드를 구별하는 의미론의 단일체도 아닙니다. 전화 기반 편집보다 쉬운 순간이있을 때 내 예제는 정확히 한 종류의 정의되지 않은 의미론에서만 작동한다는 것을 분명히 할 것입니다.
pigworker

22
많은 고뇌에 대해_|_
Landei

71

다른 답변은 간단하고 일반적인 예를 놓쳤다 고 생각합니다.

Functor이지만 Applicative가 아닌 형식 생성자입니다. 간단한 예는 다음과 같습니다.

instance Functor ((,) r) where
    fmap f (x,y) = (x, f y)

그러나에 Applicative추가 제한을 두지 않고 인스턴스 를 정의하는 방법은 없습니다 r. 특히, pure :: a -> (r, a)임의 를 정의하는 방법은 없습니다 r.

Applicative이지만 Monad가 아닌 형식 생성자입니다. 잘 알려진 예는 ZipList 입니다. ( newtype목록을 감싸고 다른 Applicative인스턴스를 제공 하는 것은 A입니다.)

fmap일반적인 방법으로 정의됩니다. 그러나 다음 pure<*>같이 정의됩니다

pure x                    = ZipList (repeat x)
ZipList fs <*> ZipList xs = ZipList (zipWith id fs xs)

이렇게 pure지정된 값을 반복하여 무한리스트를 생성하고, <*>값리스트 기능의 목록을 참아 -인가 된 I 번째 내지 함수 I 번째 요소. (표준 <*>on []i 번째 기능을 j 번째 요소 에 적용하는 모든 가능한 조합 을 생성합니다 .) 그러나 모나드를 정의하는 합리적인 방법은 없습니다 ( 이 게시물 참조 ).


화살표가 functor / applicative / monad 계층에 어떻게 맞습니까? 샘 린들리, 필립와 들러, 제레미 얄롭 이 관용구가 눈에 띄지 않고, 화살표가 꼼꼼하고, 모나드가 난잡한 모습 을 보라 . MSFP 2008. (응용 functors 관용구 라고 부릅니다 .) 요약 :

Moggi의 모나드, Hughes의 화살표 및 McBride 및 Paterson의 관용구 (응용 함수 기라고도 함)라는 세 가지 계산 개념 간의 연결을 다시 검토합니다. 우리는 관용구가 동형 사형 A ~> B = 1 ~> (A-> B)를 만족시키는 화살표와 동등하고 모나드는 동형 사형 A ~> B = A-> (1 ~ > B). 또한 관용구는 화살표에 포함되고 화살표는 모나드에 포함됩니다.


1
((,) r)적용되지 않는 펑터도 마찬가지 입니다. 그러나 이것은 일반적으로 한 번 pure에 모든 것을 정의 할 수 없기 때문 r입니다. 그것은 하나 개의 정의와 실용적 펑의 (무한) 모음을 정의하기 위해 노력하는, 따라서 언어의 간결함의 특질 pure<*>; 이런 의미에서, 어떤 콘크리트, 이후이 카운터 - 예에 대해 수학적으로 깊은 아무것도 할 수없는 것 r, ((,) r) 할 수 실용적 펑를 만들 수. 질문 : 응용 프로그램이 아닌 CONCRETE 펑터를 생각할 수 있습니까?
조지

1
이 질문에 대한 게시물로 stackoverflow.com/questions/44125484/… 를 참조하십시오 .
조지

20

functor가 아닌 형식 생성자의 좋은 예는 Set다음과 같습니다. fmap :: (a -> b) -> f a -> f b추가 제약 Ord b이 없으면 생성 할 수 없으므로 구현할 수 없습니다 f b.


16
실제로 수학적으로 우리가 것이기 때문에 좋은 예입니다 정말 이 펑터 만들 수있다.
Alexandre C.

21
@AlexandreC. 나는 그것에 동의하지 않을 것입니다. 그것은 좋은 예가 아닙니다. 수학적으로 이러한 데이터 구조는 펑터를 형성합니다. 우리가 구현할 수 없다는 사실 fmap은 언어 / 구현 문제 일뿐입니다. 또한 Set연속 모나 트로 감싸서 예상되는 모든 속성으로 모나드를 만들 수 있습니다. 이 질문을 참조하십시오 (효율적으로 수행 할 수 있는지 확실하지는 않지만).
Petr Pudlák

@ PetetPudlak, 이것은 어떻게 언어 문제입니까? 같음은 b결정 불가능할 수 있습니다.이 경우 정의 할 수 없습니다 fmap!
Turion

@Turion 결정 가능하고 정의 가능하다는 것은 두 가지 다른 것입니다. 예를 들어 알고리즘으로 결정할 수는 없지만 람다 항 (프로그램)에서 동등성을 올바르게 정의 할 수 있습니다. 어쨌든 이것은이 예제의 경우가 아닙니다. 여기서 문제는 제약 조건 으로 Functor인스턴스를 정의 할 수 없지만 언어 Ord정의가 다르거 Functor나 더 잘 정의되어있을 수 있다는 것입니다 . 사실 ConstraintKinds로 하는 것이 가능하다 이 같은 매개 변수화 할 수있는 타입의 클래스를 정의 할 수 있습니다.
Petr Pudlák

ord제약 조건을 극복 할 수 있다고해도 Set중복 된 항목을 포함 할 수 없다는 fmap것은 컨텍스트를 제단 할 수 있음을 의미합니다 . 이것은 연관성 법을 위반합니다.
존 F. 밀러

11

이 질문에 대한보다 체계적인 접근 방식을 제안하고 "하단"값이나 무한한 데이터 유형 또는 이와 유사한 것을 사용하지 않는 예제를 보여 드리고자합니다.

언제 타입 생성자가 타입 클래스 인스턴스를 갖지 못합니까?

일반적으로 형식 생성자가 특정 형식 클래스의 인스턴스를 가질 수없는 데는 두 가지 이유가 있습니다.

  1. 유형 클래스에서 필수 메소드의 유형 서명을 구현할 수 없습니다.
  2. 형식 서명을 구현할 수 있지만 필요한 법률을 충족 할 수는 없습니다.

첫 번째 종류의 예는 두 번째 종류의 예보다 쉽습니다. 첫 번째 종류의 경우 주어진 유형 서명으로 함수를 구현할 수 있는지 여부를 확인하기 만하면되고, 두 번째 종류의 경우 구현이 없음을 증명해야합니다. 법을 충족시킬 수 있습니다.

구체적인 예

  • 유형을 구현할 수 없기 때문에 functor 인스턴스를 가질 수없는 유형 생성자 :

    data F z a = F (a -> z)

이것은 입력 파라미터에 대하여 contrafunctor 아닌 펑이다 a때문에, acontravariant 위치. type signature 형식의 함수를 구현하는 것은 불가능합니다 (a -> b) -> F z a -> F z b.

  • 형식 서명을 fmap구현할 수 있지만 합법적 인 functor가 아닌 형식 생성자 :

    data Q a = Q(a -> Int, a)
    fmap :: (a -> b) -> Q a -> Q b
    fmap f (Q(g, x)) = Q(\_ -> g x, f x)  -- this fails the functor laws!

이 예제의 흥미로운 점은 반 변형 위치에서 사용하기 때문에 functor가 될 수는 없지만 올바른 유형을 구현할 있다는 것 입니다. 따라서 위에 표시된 이 구현 은 오해의 소지가 있습니다. 올바른 유형 서명이 있지만 (이 유형 서명의 유일한 가능한 구현이라고 생각합니다) functor 법률은 충족되지 않습니다. 예를 들어 ≠ 이므로 is 이지만 is 입니다.fmapFafmapfmap ididlet (Q(f,_)) = fmap id (Q(read,"123")) in f "456"123let (Q(f,_)) = id (Q(read,"123")) in f "456"456

실제로, F그것은 옹호자 일뿐입니다-그것은 펑 터나 피임 펀더가 아닙니다.

  • 의 형식 서명을 pure구현할 수 없기 때문에 적용 할 수없는 합법적 인 functor : Writer 모나드를 가져와 모노 이드 여야 (a, w)하는 제약 조건을 제거하십시오 w. 그런 다음 (a, w)out of type 값을 구성하는 것은 불가능합니다 a.

  • 의 형식 서명을 <*>구현할 수 없기 때문에 적용되지 않는 functor : data F a = Either (Int -> a) (String -> a).

  • 타입 클래스 메소드를 구현할 수 있지만 합법적이지 않은 functor :

    data P a = P ((a -> Int) -> Maybe a)

유형 생성자 Pa공변량 위치에서만 사용하기 때문에 functor 입니다.

instance Functor P where
   fmap :: (a -> b) -> P a -> P b
   fmap fab (P pa) = P (\q -> fmap fab $ pa (q . fab))

형식 서명의 유일한 구현은 <*>항상 다음을 반환하는 함수입니다 Nothing.

 (<*>) :: P (a -> b) -> P a -> P b
 (P pfab) <*> (P pa) = \_ -> Nothing  -- fails the laws!

그러나이 구현은 적용 펑터에 대한 신원 법을 충족시키지 않습니다.

  • ApplicativeMonad유형 시그니처를 bind구현할 수 없기 때문에 그렇지 않은 functor

나는 그런 예를 모른다!

  • ApplicativeMonad유형 시그니처를 bind구현할 수 있어도 법을 충족시킬 수 없기 때문에 펑터가 아닙니다 .

이 예제는 상당히 많은 논의를했기 때문에이 예제를 올바르게 증명하는 것이 쉽지 않다고 말하는 것이 안전합니다. 그러나 여러 사람들이 다른 방법으로 독립적으로 이것을 확인했습니다. 참조 |된다`데이터 증서는 빈 = 모나드 페어? 추가 토론.

 data B a = Maybe (a, a)
   deriving Functor

 instance Applicative B where
   pure x = Just (x, x)
   b1 <*> b2 = case (b1, b2) of
     (Just (x1, y1), Just (x2, y2)) -> Just((x1, x2), (y1, y2))
     _ -> Nothing

합법적 인 Monad사례 가 없음을 증명하는 것은 다소 성가신 일 입니다. 비모 노드 동작의 이유 bind는 함수 f :: a -> B b가를 반환 Nothing하거나 Just다른 값을 반환 할 때 자연스럽게 구현할 수 있는 방법이 없기 때문 입니다 a.

Maybe (a, a, a)모나드가 아닌를 고려 하고 구현을 시도하는 것이 더 명확 할 것 join입니다. 직관적으로 합리적인 구현 방법이 없다는 것을 알게 될 것입니다 join.

 join :: Maybe (Maybe (a, a, a), Maybe (a, a, a), Maybe (a, a, a)) -> Maybe (a, a, a)
 join Nothing = Nothing
 join Just (Nothing, Just (x1,x2,x3), Just (y1,y2,y3)) = ???
 join Just (Just (x1,x2,x3), Nothing, Just (y1,y2,y3)) = ???
 -- etc.

로 표시된 경우 ???, 우리는 Just (z1, z2, z3)6 가지 유형의 값 중에서 합리적이고 대칭적인 방식으로 생산할 수 없음이 분명해 보인다 a. 우리는 확실히이 6 가지 값 중 임의의 부분 집합을 선택할 수 있습니다 Maybe. 귀국 Nothing도 법률을 충족하지 않습니다.

  • 모나드 가 아니지만 연관성 이있는 트리와 유사한 데이터 구조-신분법에bind 실패합니다.

일반적인 나무와 같은 모나드 (또는 "펑터 모양의 가지가있는 나무")는 다음과 같이 정의됩니다.

 data Tr f a = Leaf a | Branch (f (Tr f a))

이것은 functor에 대한 무료 모나드 f입니다. 데이터의 모양은 각 분기점이 하위 트리의 "기능이 많은"트리입니다. 표준 이진 트리는로 얻을 수 있습니다 type f a = (a, a).

우리가 functor 모양의 잎을 f만들어서이 데이터 구조를 수정하면 , 우리는 내가 "세미 모나드 (semimonad)"라고 부르는 것을 얻습니다. 그것은 bind자연 성과 연관성 법칙을 만족 시키지만 그 pure방법 은 신분법 중 하나에 실패합니다. "세미 모나드는 endofunctors의 범주에서 세미 그룹입니다, 문제는 무엇입니까?" 이것은 타입 클래스 Bind입니다.

간단하게하기 위해 join메소드 대신 다음을 정의합니다 bind.

 data Trs f a = Leaf (f a) | Branch (f (Trs f a))
 join :: Trs f (Trs f a) -> Trs f a
 join (Leaf ftrs) = Branch ftrs
 join (Branch ftrstrs) = Branch (fmap @f join ftrstrs)

가지 이식은 표준이지만 잎 이식은 비표준이며 Branch . 이것은 연관성 법의 문제는 아니지만 신원 법 중 하나를 위반합니다.

다항식 유형에는 언제 모나드 인스턴스가 있습니까?

어느 쪽도 아니 펑의 Maybe (a, a)Maybe (a, a, a)합법적 할 수는 없으며, Monad그들은 분명히 있지만, 인스턴스를 Applicative.

더 -이 펑은 속임수가 없다 Void거나 bottom어디서든, 어떤 까다로운 게으름 / 엄격함, 아니 무한 구조 및 어떤 타입의 클래스 제약 조건을. Applicative인스턴스는 완전히 표준입니다. 이러한 기능에 대해 기능 returnbind구현이 가능하지만 모나드의 법칙을 만족 시키지는 않습니다. 다시 말해, 이러한 기능은 특정 구조가 없기 때문에 모나드가 아닙니다 (그러나 정확히 무엇이 없는지 이해하기는 어렵습니다). 예를 들어, functor를 조금만 변경하면 모나드로 만들 수 있습니다. data Maybe a = Nothing | Just a는 모나드입니다. 또 다른 유사한 functor data P12 a = Either a (a, a)도 모나드입니다.

다항식 모나드 구성

일반적으로 다음은 Monad다항식 유형에서 합법적 인 내용을 생성하는 일부 구성입니다 . 이 모든 구성에서 M모나드는 다음과 같습니다.

  1. type M a = Either c (w, a)wmonoid는 어디에 있습니까
  2. type M a = m (Either c (w, a))m모나드는 어디에 있고 w어떤 모노 이드인가
  3. type M a = (m1 a, m2 a)모나드는 어디에 m1있고m2
  4. type M a = Either a (m a)m모나드는 어디에 있습니까

첫 번째 건설은 WriterT w (Either c)이고 두 번째 건설은 WriterT w (EitherT c m)입니다. : 세 번째 구성은 모나드의 성분 와이즈 제품 pure @M의 성분 와이즈 곱으로 정의 pure @m1하고 pure @m2, 그리고 join @M(예를 들어 간 제품 데이터를 생략함으로써 정의 m1 (m1 a, m2 a)에 매핑 m1 (m1 a)튜플의 두 번째 부분을 생략함으로써)

 join :: (m1 (m1 a, m2 a), m2 (m1 a, m2 a)) -> (m1 a, m2 a)
 join (m1x, m2x) = (join @m1 (fmap fst m1x), join @m2 (fmap snd m2x))

네 번째 구조는 다음과 같이 정의됩니다.

 data M m a = Either a (m a)
 instance Monad m => Monad M m where
    pure x = Left x
    join :: Either (M m a) (m (M m a)) -> M m a
    join (Left mma) = mma
    join (Right me) = Right $ join @m $ fmap @m squash me where
      squash :: M m a -> m a
      squash (Left x) = pure @m x
      squash (Right ma) = ma

나는 네 가지 구조물 모두 합법적 인 모나드를 생산하는지 확인했습니다.

나는 추측 다항식 모나드에 대한 다른 구조물이 없음. 예를 들어, 펑 터는 Maybe (Either (a, a) (a, a, a, a))이러한 구성을 통해 얻지 못하므로 모나 딕이 아닙니다. 그러나 Either (a, a) (a, a, a)이 세 가지 모나드의 제품에 동형 때문에 모나드이다 a, a하고 Maybe a. 또한, Either (a,a) (a,a,a,a)그것은의 제품에 동형 때문에 모나드이다 a하고 Either a (a, a, a).

위에 표시된 네 가지 구성을 통해 a예를 들어 여러 가지 수의 제품에 대한 합계를 얻을 Either (Either (a, a) (a, a, a, a)) (a, a, a, a, a))수 있습니다. 이러한 모든 유형 생성자는 하나 이상의 Monad인스턴스를 갖습니다 .

물론 그러한 모나드에 어떤 유스 케이스가 존재할 수 있는지는 여전히 남아 있습니다. 또 다른 문제는 Monad구성 1-4를 통해 파생 된 인스턴스가 일반적으로 고유하지 않다는 것입니다. 예를 들어, 형식 생성자 에는 두 가지 방식으로 인스턴스 type F a = Either a (a, a)가 제공 될 수 있습니다 Monad. 모나드를 사용하는 구성 4 (a, a)및 유형 isomorphism을 사용하는 구성 3 Either a (a, a) = (a, Maybe a). 다시 한번, 이러한 구현에 대한 사용 사례를 찾는 것은 명백하지 않습니다.

임의의 다항식 데이터 유형, Monad인스턴스 가 있는지 여부를 인식하는 방법에 대한 질문이 남아 있습니다 . 다항식 모나드에 대한 다른 구성이 없음을 증명하는 방법을 모르겠습니다. 나는 지금까지이 질문에 대답 할 이론이 없다고 생각합니다.


내 생각 B 이다 모나드. 이 바인드에 대한 반례를 줄 수 있습니까 Pair x y >>= f = case (f x, f y) of (Pair x' _,Pair _ y') -> Pair x' y' ; _ -> Empty?
Franky

@Franky 연관성은 선택이 정의와 함께 실패 ff x이다 Empty하지만 f yA는 Pair, 다음 단계에 모두 있습니다 Pair. 본인은 법이이 구현 또는 다른 구현에 적용되지 않는지 직접 확인했습니다. 하지만 그렇게하는 것은 상당히 힘든 일입니다. 나는 이것을 이해하는 더 쉬운 방법이 있었으면 좋겠다!
winitzki

1
@Turion이 인수는 다른 값을 포함하지 않기 Maybe때문에 적용 Maybe되지 않습니다 a.
Daniel Wagner

1
@Turion 나는 몇 페이지의 계산으로 이것을 증명했다. "자연적인 방법"에 대한 논쟁은 단지 경험적 설명입니다. Monad인스턴스 기능으로 구성 return하고 bind충족 법률있다. 필요한 유형에 맞는 두 가지 구현 return과 25 가지 구현이 bind있습니다. 직접 계산을 통해 구현 중 어느 것도 법을 충족하지 않음을 보여줄 수 있습니다. 필요한 작업의 양을 줄이기 위해 먼저 신원 법 join대신에 bind사용했으며 우선 법을 사용했습니다. 그러나 그것은 상당한 일이었습니다.
winitzki

1
@duplode 아니요, Traversable필요 하다고 생각하지 않습니다 . m (Either a (m a))로를 사용하여 변환 pure @m됩니다 m (Either (m a) (m a)). 그럼 사소하게 Either (m a) (m a) -> m a, 우리는 사용할 수 있습니다 join @m. 그것이 제가 법을 확인한 구현이었습니다.
winitzki
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.