Apakah satu-satunya `FlippyFloppyMorphism`` const mempty`?
Di Haskell, kami memiliki fakta menarik bahwa semua tipe konstruktor f :: * -> *yang secara simultan a Functordan a Contravariantadalah bayangan dalam parameter tipenya:
phantom :: (Functor f, Contravariant f) => f x -> f y
Cara lain untuk meletakkan ini adalah bahwa setiap jenis konstruktor yang secara simultan a Functors dan a Contravariantsecara alami isomorfik Const x, untuk beberapa x.
Ini menyiratkan bahwa satu-satunya cara (hingga isomorfisme) untuk membuat instance kelas:
class FlippyFloppyFunctor f
where
ffmap :: Either (y -> x) (x -> y) -> f x -> f y
sehingga mematuhi hukum functor:
ffmap (Left id) = id
ffmap (Right id) = id
ffmap (Left (g . f)) = ffmap (Left f) . ffmap (Left g)
ffmap (Right (f . g)) = ffmap (Right f) . ffmap (Right g)
adalah:
weirdmap :: Either (y -> x) (x -> y) -> Const r x -> Const r y
weirdmap = const $ \(Const x) -> Const x
yaitu modulo tipe baru const id,.
Saya merasa sulit untuk memahami mengapa ini adalah satu-satunya fungsi dari tipenya yang memenuhi batasan, meskipun saya dapat memahami berbagai argumen informal yang melibatkan absurd :: Void -> a/ discard :: a -> ()mengapa keberadaan peta semacam itu menyiratkan functor "adalah hantu" dalam tipenya parameter.
Untuk memahaminya dengan lebih baik, saya mencoba menyederhanakan masalah. Daripada memikirkan FlippyFloppyFunctor, mari pikirkan:
class (Monoid a, Monoid b) => FlippyFloppyMorphism a b
where
ffmorph :: Either a a -> b
dengan hukum analog:
ffmorph (Left mempty) = mempty
ffmorph (Right mempty) = mempty
ffmorph (Left (y <> x)) = ffmorph (Left x) <> ffmorph (Left y)
ffmorph (Right (x <> y)) = ffmorph (Right x) <> ffmorph (Right y)
Dengan asumsi itu adan b merupakan monoid non-komutatif , apakah masih benar bahwa satu-satunya implementasi yang sah FlippyFloppyMorphismadalah const mempty? Apakah masih mungkin untuk menjelaskan mengapa morfisme harus menjadi "hantu" dalam monoid masukan, tanpa memiliki Voidatau ()untuk merujuk?
Jawaban
Bagi saya, jawaban dalam kasus umum adalah "tidak", karena monoid dapat bersifat komutatif.
Jika monoid itu komutatif, maka Dual amonoid itu sama dengan a, dan Either a asama dengan a, dan karenanya kita hanya merosot untuk menanyakan apakah ffmorphsatu-satunya homomorfisme monoid a -> b. Jawabannya adalah tidak".
Misalnya, untuk monoid komutatif penjumlahan, kami memiliki replicate 'a' :: Either (Sum Int) (Sum Int) -> String, di mana:
replicateA (Left 0) = ""
replicateA (Right 0) = ""
replicateA (Left (y + x)) = replicateA (Left x) ++ replicateA (Left y)
replicateA (Right (x + y)) = replicateA (Left x) ++ replicateA (Left y)
Namun, saya pikir mungkin kasusnya untuk _non_commutative monoids, satu-satunya penerapan yang mungkin adalah const mempty(yang saya masih belum memiliki buktinya).