这是一个完美的用例DerivingVia
(我注意到我没有足够仔细地阅读这个问题,你必须使用一种newtype
或另一种方式:这个解决方案不是你所希望的,但它是惯用的)
{-# Language DerivingVia #-}
{-# Language StandaloneKindSignatures #-}
import Control.Applicative (Alternative)
import Control.Monad (MonadPlus)
import Control.Monad.Fix (MonadFix)
import Control.Monad.Trans.Maybe
import Control.Monad.Zip (MonadZip)
import Data.Kind (Type)
type Fortunate :: Type -> Type
newtype Fortunate a = Fortunate [Maybe a]
deriving
( Functor, Foldable, Applicative, Alternative
, Monad, MonadPlus, MonadFail, MonadFix, MonadZip
)
via MaybeT []
其中一些实例(Functor, Foldable, Applicative, Alternative)
可以通过Compose Maybe []
.
要列出可以派生的实例,请使用:instances
命令
>> :instances MaybeT []
instance [safe] Alternative (MaybeT [])
-- Defined in ‘Control.Monad.Trans.Maybe’
instance [safe] Applicative (MaybeT [])
-- Defined in ‘Control.Monad.Trans.Maybe’
...
>> :instances Compose Maybe []
instance Alternative (Compose Maybe [])
-- Defined in ‘Data.Functor.Compose’
instance Applicative (Compose Maybe [])
-- Defined in ‘Data.Functor.Compose’
...
因为是一个应用程序,您可以通过逐点(惯用的,应用程序)提升Fortunate
推导出:(Semigroup, Monoid, Num, Bounded)
import Data.Monoid (Ap(..))
..
deriving (Semigroup, Monoid, Num, Bounded)
via Ap Fortunate a
其中(<>) = liftA2 (<>)
, abs = liftA abs
, mempty = pure mempty
, minBound = pure minBound
.