Короче говоря : ваше определение для (<>)
не может использоваться в качестве бинарного оператора для моноида.Если только вы не можете гарантировать, что существует только одно возможное значение для a
(или b
, если мы используем Snd
в качестве конструктора для "нейтрального элемента").
в соответствии с вышеизложеннымправила, очевидно, Fst x
должен быть mempty
, если это был Monoid
.
Точно, , если это был моноид [вики] .Но для моноида можно доказать, что существует * точно один элемент идентичности.Доказательство состоит в следующем: если есть два нейтральных элемента e 1 и e 1 , то это означает, что e 1 *e 2 = e 1 , но в то же время e 1 *e 2 = e 2 (поскольку a⊕e = e⊕a = a выполняется с e единичным элементом), что означаетчто e 1 = e 2 имеет место, и, таким образом, они совпадают.
Теперь в вашем определении (<>)
естьнет такой элемент идентичности.В самом деле, скажите, что этот элемент Fst e
, тогда он должен содержать следующее:
Fst e <> Fst a = Fst a
, которое содержит (первая строка вашего определения), но он также должен содержать следующее:
Fst a <> Fst e = Fst a
и это, согласно вашей функции (<>)
, будет удерживаться, только если a
равно e
.Таким образом, единственный способ объявить это моноидом - это определить только одно значение в конструкторе Fst
, как, например, @ leftroundabout , например:
instance Monoid (Or () b) where
mempty = Fst ()
mappend = (<>)
Таким образом, мы можем заключить, что ваша (<>)
функция не подходит как бинарный оператор для моноида.Вам нужно будет придумать другой бинарный оператор, структурированный таким образом, чтобы его можно было использовать в моноиде.
Теперь все еще возможно, что элемент идентификации имеет форму Snd e
, но опять же:
(Snd x) <> (Snd e) = Snd x
(Snd e) <> (Snd x) = Snd x
должны оба храниться, тогда как в вашей реализации:
(Snd x) <> (Snd _)= Snd x
последнее не будет выполняться (поскольку x
может отличаться от e
).