모든 고정 된 크기의 용기는 강력한 단일체 펑터입니까?


9

Applicativetypeclass을 나타내는 LAX monoidal 펑 해당 입력 기능의 범주에 직교 monoidal 구조를 유지.

다시 말해서, (,)단일체 구조 를 형성하는 표준 동 형사상이 주어지면 :

-- Implementations left to the motivated reader
assoc_fwd :: ((a, b), c) -> (a, (b, c))
assoc_bwd :: (a, (b, c)) -> ((a, b), c)

lunit_fwd :: ((), a) -> a
lunit_bwd :: a -> ((), a)

runit_fwd :: (a, ()) -> a
runit_bwd :: a -> (a, ())

타입 클래스와 그 법칙은 다음과 같이 작성 될 수 있습니다 :

class Functor f => Applicative f
  where
  zip :: (f a, f b) -> f (a, b)
  husk :: () -> f ()

-- Laws:

-- assoc_fwd >>> bimap id zip >>> zip
-- =
-- bimap zip id >>> zip >>> fmap assoc_fwd

-- lunit_fwd
-- =
-- bimap husk id >>> zip >>> fmap lunit_fwd

-- runit_fwd
-- =
-- bimap id husk >>> zip >>> fmap runit_fwd

동일한 구조와 관련하여 오플 렉서 일체형 의 펑터가 어떻게 보일지 궁금 할 것입니다.

class Functor f => OpApplicative f
  where
  unzip :: f (a, b) -> (f a, f b)
  unhusk :: f () -> ()

-- Laws:

-- assoc_bwd <<< bimap id unzip <<< unzip
-- =
-- bimap unzip id <<< unzip <<< fmap assoc_bwd

-- lunit_bwd
-- =
-- bimap unhusk id <<< unzip <<< fmap lunit_bwd

-- runit_bwd
-- =
-- bimap id unhusk <<< unzip <<< fmap runit_bwd

정의와 법에 관련된 유형에 대해 생각하면 실망스러운 진실이 드러납니다. OpApplicative다음보다 더 구체적인 제약은 없습니다 Functor.

instance Functor f => OpApplicative f
  where
  unzip fab = (fst <$> fab, snd <$> fab)
  unhusk = const ()

그러나 모든 Applicativefunctor (실제로 any Functor)는 사소한 것이지만, laxities 와 oplaxities OpApplicative사이에 반드시 좋은 관계가있는 Applicative것은 OpApplicative아닙니다. 따라서 직교 일측 체 구조를 갖는 강력한 일 측성 펑터를 찾을 수 있습니다 .

class (Applicative f, OpApplicative f) => StrongApplicative f

-- Laws:
-- unhusk . husk = id
-- husk . unhusk = id
-- zip . unzip = id
-- unzip . zip = id

위의 첫 번째 법칙은 사소한 데, 그 유형의 유일한 거주자 () -> ()는의 신분 함수입니다 ().

그러나 나머지 세 가지 법칙과 하위 클래스 자체는 사소한 것이 아닙니다 . 특히 모든 사람 Applicative이이 클래스의 합법적 인 사례는 아닙니다 .

다음은 Applicative합법적 인 사례를 선언 할 수있는 몇 가지 기능 입니다 StrongApplicative.

  • Identity
  • VoidF
  • (->) r
  • Monoid m => (,) m (답변 참조)
  • Vec (n :: Nat)
  • Stream (무한대)

그리고 여기에 Applicative우리가 할 수없는 것들이 있습니다 :

  • []
  • Either e
  • Maybe
  • NonEmptyList

패턴은 여기에 제안 StrongApplicative클래스는 의미 인 FixedSize"고정 크기"클래스, * 수단은 다양성 것을 ** 의 주민 a의 주민에이 f a고정됩니다.

이것은 두 가지 추측으로 언급 될 수 있습니다.

  • Applicative유형 인수의 요소로 구성된 "고정 크기"컨테이너를 나타내는 모든 것은StrongApplicative
  • StrongApplicative발생 횟수가 a다를 수있는 인스턴스가 없습니다.

누구나 이러한 추측을 반증하는 반례, 또는 그것이 참인지 거짓인지를 보여주는 설득력있는 추론을 생각할 수 있습니까?


* 형용사 "고정 크기"를 올바르게 정의하지 않았다는 것을 알고 있습니다. 불행히도 작업은 약간 순환 적입니다. 나는 "고정 크기"컨테이너에 대한 공식적인 설명을 모른다. StrongApplicative지금까지 최선의 시도입니다.

그러나 이것이 좋은 정의인지 평가하려면 비교할 것이 필요합니다. functor가 형식 인수의 거주자와 관련하여 주어진 크기 또는 다중성을 갖는 것이 무엇을 의미하는지에 대한 공식 / 비공식적 정의를 감안할 때, 문제는 실체의 존재 StrongApplicative가 고정되고 다양한 크기의 functor를 정확하게 구별 하는지 여부 입니다.

기존의 공식적인 정의를 알지 못하고 "고정 크기"라는 용어를 사용하면서 직감에 호소하고 있습니다. 그러나 누군가가 이미 functor의 크기에 대한 기존 형식을 알고 StrongApplicative그것을 비교할 수 있다면 훨씬 좋습니다.

** "다중성 (multiplicity)"이란 용어는 functor의 코 도메인 유형의 거주자에서 functor의 매개 변수 유형의 임의 요소가 "얼마나 많은"지를 의미합니다. 이다 없이 펑이 적용되는 특정 유형에 대하여, 따라서 파라미터 유형의 특정 주민 관계없이.

이것에 대해 정확하지 않으면 주석에 약간의 혼란이 생겼으므로 다음은 다양한 펑터의 크기 / 다중성을 다음과 같이 고려할 수있는 몇 가지 예입니다.

  • VoidF: 고정, 0
  • Identity: 고정, 1
  • Maybe: 변수, 최소 0, 최대 1
  • []: 변수, 최소 0, 최대 무한
  • NonEmptyList: 가변, 최소 1, 최대 무한
  • Stream: 고정, 무한
  • Monoid m => (,) m: 고정, 1
  • data Pair a = Pair a a: 고정, 2
  • Either x: 변수, 최소 0, 최대 1
  • data Strange a = L a | R a: 고정, 1

의견은 긴 토론을위한 것이 아닙니다. 이 대화는 채팅 으로 이동 되었습니다 .
Samuel Liew

"고정 크기"의 한 가지 가능한 정의는 "표현 가능"입니다. 표현할 수있는 모든 펑 터는 여기에 설명 된 의미에서 강력한 응용 프로그램 (->) r입니다.
다니엘 바그너

@DanielWagner 나는 강력한 적용을 상속 받기 위해서는 동 형사상 이상의 것이 필요하다고 생각한다 (->) r. 강력한 적용 구조를 유지하려면 동형의 구성 요소가 필요합니다. 어떤 이유로 Representable하스켈 typeclass 신비한가 tabulate . return = return(정말 심지어 비 모나드 펑터에 대한 이해가되지 않습니다) 법을, 그러나 그것은 우리에게 우리가 그런 말을하는 데 필요한 조건의 1/4 제공 tabulate하고 zipmonoids의 적절한 카테고리의 morphisms됩니다 . 다른 3 가지 규칙은 추가로 요구되는 법률입니다.
Asad Saeeduddin

죄송합니다, 그것은해야한다 " tabulateindex... 적절한 카테고리의 morphisms입니다"
아사드 Saeeduddin

@AsadSaeeduddin 문서에 법이 명시되어있는 방식은 이상하게 들리 겠지만 요구하는 return것은 심각한 문제가 아니라는 것이 밝혀졌습니다 . cotraverse getConst . Constreturn/ pure의 관점에서 기본 구현이며 Distributive배포자 / 표현자가 고정 된 모양을 갖기 때문에 해당 구현은 고유합니다.
듀플로드

답변:


4
  • Applicative유형 인수의 요소로 구성된 "고정 크기"컨테이너를 나타내는 모든 것은StrongApplicative
  • StrongApplicative발생 횟수가 a다를 수있는 인스턴스가 없습니다.

누구나 이러한 추측을 반증하는 반례, 또는 그것이 참인지 거짓인지를 보여주는 설득력있는 추론을 생각할 수 있습니까?

나는 그 첫 번째 추측에 대해 확신하지 못하고 @AsadSaeeduddin과의 토론을 바탕으로 증명하기 어려울 수 있지만 두 번째 추측은 사실입니다. 이유를 보려면 StrongApplicative법을 고려하십시오 husk . unhusk == id. 즉 x :: f (), husk (unhusk x) == x. 그러나 하스켈에 unhusk == const (), 그래서 법은 모든 말과 동일합니다 x :: f (), husk () == x. 그러나 차례로 이것은 단지이 유형의 하나 개의 고유 한 값을 존재할 수 있음을 의미 f ()두 개의 값이 있다면 : x, y :: f ()다음 x == husk ()husk () == y그래서 x == y. 그러나 가능한 f ()값 이 하나만 있으면 f고정 된 모양이어야합니다. (예를 들어 data Pair a = Pair a a, type의 값은 하나 뿐이지 만 Pair (), 또는 Pair () ()여러 유형의 값이 있습니다.)Maybe ()[()]husk . unhusk == idf고정 된 모양이어야 함을 나타냅니다 .


흠. "유형의 하나의 고유 한 값만이 존재할 수있다"는 것은 화려한 GADT와 물건이있을 때 "다양 할 수없는 f ()발생 횟수"를 의미한다는 것이 정말로 분명 a합니까?
다니엘 바그너

@DanielWagner“ a변할 수없는 횟수 ”는 StrongApplicative인스턴스에 충분한 조건이 아니라는 것이 밝혀졌습니다 . 예를 들어, data Writer w a = Writer (w,a)다양하지 않은 다중성이 a있지만 StrongApplicative. 변하지 않는 functor의 모양이 실제로 필요합니다 f (). 이것이 싱글 톤 의 결과라고 생각 합니다.
bradrn

그것이 어떻게 관련되어 있는지 잘 모르겠습니다. 답에서 두 번째 추측을 확인하면서 "강력한 적용"은 "하나의 구별 f ()" a은 " 발생 횟수는 변할 수 없음 "을 의미한다고 주장합니다 . 나는 그 주장의 마지막 단계가 분명히 사실이 아니라고 반대합니다. 예를 들어 data Weird a where One :: a -> Weird a; None :: Weird Bool. type의 고유 한 값이 Weird ()있지만 다른 생성자에는 다양한 수의들이 a있습니다. (여기서 완전한 반례 Functor는 아니지만 어려운 점을 어떻게 알 수 있습니까?)
Daniel Wagner

@DanielWagner Weird ()싱글 포인트 이지만 고정 된 모양이 아니라는 것이 좋습니다. 그러나 Weird하지 않은 것입니다 Functor그래서이 될 수 없다, StrongApplicative어쨌든. 나는 관련 추측 될 것이라고 가정 해 경우 fA는 Functor않습니다, f ()싱글은 그 의미있는 f고정 된 모양입니다 ? 나는 이것이 사실이라고 강력하게 의심하지만, 당신이 언급했듯이 실제로 아직 아무런 증거가 없습니다.
bradrn

5

우리는 이러한 질문들 중 적어도 하나에 대해 부정적인 대답을 할 수 있습니다.

형식 인수의 요소로 구성된 "고정 크기"컨테이너를 나타내는 모든 응용 프로그램은 StrongApplicative의 인스턴스입니다.

사실 StrongApplicative원래 질문에 합법적 인 예 중 하나 가 잘못되었습니다. 예를 들어, 작가의 응용 프로그램 Monoid => (,) m은 없습니다 .StrongApplicativehusk $ unhusk $ ("foo", ()) == ("", ()) /= ("foo", ())

마찬가지로 고정 크기 컨테이너의 예는 다음과 같습니다.

data Strange a = L a | R a

우리가 husk = Leftthen 을 정의하면 husk $ unhusk $ Right () /= Right ()그 반대도 마찬가지 이기 때문에 고정 된 다중도 1의 고정 된 적용법은 아닙니다 . 이것을 보는 동등한 방법은 이것이 당신이 선택한 monoid에 대한 작가 응용 프로그램이라는 것입니다 Bool.

따라서 "고정 크기"응용 프로그램은 존재하지 않습니다 StrongApplicative. 모든 StrongApplicative크기가 고정 크기 인지 여부 는 여전히 남아 있습니다.


5

"고정 크기 컨테이너"의 정의로 표현할 수있는 functors를 보자.

class Representable f where
    type Rep f
    tabulate :: (Rep f -> a) -> f a
    index :: f a -> Rep f -> a

실제 Representable에는 몇 가지 법칙과 수퍼 클래스가 있지만이 답변의 목적 상 실제로 두 가지 속성 만 필요합니다.

tabulate . index = id
index . tabulate = id

(좋아요, 우리는 또한 법률 준수가 필요합니다 instance StrongApplicative ((->) r). 쉬운 peasy, 당신은 이미 그것이 존재한다는 것에 동의합니다.)

우리가 그 정의를 취하면, 그 추측 1을 확인할 수 있습니다.

Applicative형식 인수의 요소로 구성된 "고정 크기"컨테이너를 나타내는 모든 것은 [law-abiding] 인스턴스입니다.StrongApplicative

사실이다. 방법은 다음과 같습니다.

instance Representable f => Applicative f where
    zip (fa, fb) = tabulate (zip (index fa, index fb))
    husk = tabulate . husk

instance Representable f => OpApplicative f where
    unzip fab = let (fa, fb) = unzip (index fab) in (tabulate fa, tabulate fb)
    unhusk = unhusk . index

instance Representable f => StrongApplicative f

이 증명하는 법을 많이하지만 나는 빅 4에 그냥 초점을 맞출 것입니다 StrongApplicative추가 - 당신은 아마 이미 리드에 대한 것들을 생각 Applicative하고 OpApplicative있지만, 그렇게하지 않으면, 그 증거는 아래 사항들과 같이 ( 차례로 서로 아주 많이 보입니다). 명확하게하기 위해, 내가 사용 zipf, huskf기능, 예를 들어, 등, 그리고 zipr, huskr당신이있는 이는 추적 할 수 있도록 표현할 예를 들어, 등. (그리고 우리가 가정하려는 것으로 간주하지 않는 것을 쉽게 확인할 수 있습니다! 증명할 unhuskf . huskf = id때 사용 unhuskr . huskr = id하는 것이 좋지만 unhuskr . huskr = id동일한 증거 로 가정 하는 것은 잘못 입니다.)

각 법의 증거는 기본적으로 같은 방식으로 진행됩니다 Representable.

unhuskr . huskr
= { def. of unhuskr and huskr }
(unhuskf . index) . (tabulate . huskf)
= { index . tabulate = id }
unhuskf . huskf
= { unhuskf . huskf = id }
id

huskr . unhuskr
= { def. of huskr and unhuskr }
(tabulate . huskf) . (unhuskf . index)
= { huskf . unhuskf = id }
tabulate . index
= { tabulate . index = id }
id

zipr (unzipr fab)
= { def. of unzipr }
zipr (let (fa, fb) = unzipf (index fab) in (tabulate fa, tabulate fb))
= { def. of zipr }
let (fa, fb) = unzipf (index fab) in tabulate (zipf (index (tabulate fa), index (tabulate fb)))
= { index . tabulate = id }
let (fa, fb) = unzipf (index fab) in tabulate (zipf (fa, fb))
= { def. of (fa, fb) }
tabulate (zipf (unzipf (index fab)))
= { zipf . unzipf = id }
tabulate (index fab)
= { tabulate . index = id }
fab

unzipr (zipr (fa, fb))
= { def. of zipr }
unzipr (tabulate (zipf (index fa, index fb)))
= { def. of unzipr }
let (fa', fb') = unzipf (index (tabulate (zipf (index fa, index fb))))
in (tabulate fa', tabulate fb')
= { index . tabulate = id }
let (fa', fb') = unzipf (zipf (index fa, index fb))
in (tabulate fa', tabulate fb')
= { unzipf . zipf = id }
let (fa', fb') = (index fa, index fb)
in (tabulate fa', tabulate fb')
= { def. of fa' and fb' }
(tabulate (index fa), tabulate (index fb))
= { tabulate . index = id }
(fa, fb)

현재 숙고 : instance StrongApplicative f => Representable f where type Rep f = forall x. f x -> x. index쉽습니다. 나는 tabulate아직 트릭을 풀지 못했지만 열광적으로 가깝습니다.
다니엘 바그너

@AsadSaeeduddin과의 토론에서 나는 동일한 StrongApplicative사례 를 찾았 지만 법을 증명할 수는 없었습니다. 그것을 알아 낸 것을 축하합니다! 나는 Representable주어진 인스턴스 를 수행하려고 시도했지만 StrongApplicative좋은 Rep유형을 생각할 수 없었습니다 . 궁금한 점이 있습니다 forall x. f x -> x.
bradrn

@bradrn 가설은 이러한 것들이 어떤 요소가 들어가는 고정 된 "구멍"을 가지고 있다는 가설을 상기하십시오. 그런 다음 유형의 함수 forall x. f x -> x는 정확히 구멍을 선택하고 해당 구멍의 값을 반환하는 함수입니다. (그리고 구현 방법에 대해 생각하면서 tabulate유형에 대한 반대 의견을 내놓았습니다 unhusk. 자세한 내용은 질문 자체에 대한 의견을 참조하십시오.)
Daniel Wagner

감사합니다 @DanielWagner! 그것은 정말 영리한 접근법입니다. 저는 그런 생각을하지 않았습니다.
bradrn

그것을 구현하려고 시도한 후에는 그것이 forall x. f x -> x작동 한다고 확신하지 않습니다 Rep. 내 추론 즉,이를 사용하고 Rep, 당신이 쓸 수 index에 대한 어떤 종류뿐만 아니라 StrongApplicative사람 - 내가 그 생각 때문에 forall x. f x -> x너무 일반적 일 수 있습니다.
bradrn
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.