Я пытаюсь сделать игру в крестики-нолики, и я решил построить типы для ячеек (элементов доски) и доски следующим образом:
data Cell = X | O deriving (Show, Eq)
type Board = [[Maybe Cell]]
Здесь Ничто не представляетпустая ячейка, (Just X) и (Just O) представляют ячейки, заполненные соответственно X и O.
Я хотел бы определить (может быть Cell) как моноид следующим образом:
instance Monoid (Maybe Cell) where
mempty = Nothing
mappend Nothing x = x
mappend (Just x) _ = (Just x)
И Board как еще один моноид с
instance Monoid Board where
mempty = [[Nothing, Nothing, Nothing]
,[Nothing, Nothing, Nothing]
,[Nothing, Nothing, Nothing]]
mappend = zipWith (zipWith mappend)
-- where the right-hand-side mappend is the addition on (Maybe Cell)
Я знаю, что мог бы реализовать это абсолютно без моноидов, но я пытаюсь исследовать поле, и это просто очень хороший способ написать это.
Проблема, которую я получаю, состоит в том, что Maybe
моноидный экземпляр уже определен в GHC.Base
следующим образом:
instance Semigroup a => Monoid (Maybe a)
Это определение очень отличается от того, что я хочу, но оно вызывает дублированиеобъявления экземпляров, поэтому я не могу просто проигнорировать это.
Я пытаюсь скрыть Monoid
экземпляр (Maybe a)
от GHC.Base
, чтобы избежать дублирования экземпляров.Я много пытался найти это, но не смог найти способ это скрыть.Я не могу скрыть все Monoid
или все Semigroup
, потому что мне нужны их функции, но мне нужно скрыть это объявление конкретного экземпляра.Может ли кто-нибудь помочь мне с этим?
ПРИМЕЧАНИЕ: я использую FlexibleInstances.