0

几天前,我试图通过创建一个新的 monad 实例来证明 monad 定律,但我发现自己陷入了定义新的 monad 实例的困境。

{-# LANGUAGE DeriveFunctor, InstanceSigs #-}
import Control.Monad

newtype Test a = Test { getTest :: [Maybe a] }
  deriving Functor

instance Applicative Test where
  pure = return
  (<*>) = liftM2 ($)

instance Monad Test where
  return :: a -> Test a
  return a = Test $ [Just a]
  
  (>>=) :: Test a -> (a -> Test b) -> Test b
  g >>= f = concat (map f g)  --Tried to do something like this

我在 list monad 定义之后尝试了一些东西,但是因为 concat 需要 [[a]] 但在这里它得到 [Test b] ,所以可能有其他可用的函数,或者有没有办法让 concat 在 newType 上工作?任何建议表示赞赏。谢谢。

4

2 回答 2

2

type别名不同,newtype包装器需要手动应用和删除。替换g >>= f = concat (map f g)Test g >>= f = Test $ concat (map (getTest . f) g)

这只会给您留下一个类型错误:ghas type[Maybe a]而不是 required [a]。我们可以添加一个catMaybes(needs import Data.Maybe) 来解决这个问题:Test g >>= f = Test $ concat (map (getTest . f) $ catMaybes g). 现在它编译了。

不幸的是,这种情况是不合法的。我将把它作为练习留给读者确定为什么不这样做,以及它是否可以轻松修复。

于 2020-11-27T04:18:48.797 回答
0

它们可以推导出变压器MaybeT []

{-# Language DerivingVia              #-}
{-# Language StandaloneKindSignatures #-}

import Control.Applicative       (Alternative)
import Control.Monad             (MonadPlus)
import Control.Monad.Fix         (MonadFix)
import Control.Monad.Trans.Maybe (MaybeT(..))
import Control.Monad.Zip         (MonadZip)
import Data.Kind                 (Type)

type    Test :: Type -> Type
newtype Test a = Test { getTest :: [Maybe a] }
 deriving (Functor, Foldable, Applicative, Alternative, Monad, MonadFail, MonadFix, MonadPlus, MonadZip)
 via MaybeT []

:instances MaybeT []

>> :instances MaybeT []
instance [safe] GHC.Base.Alternative (MaybeT [])
  -- Defined in ‘Control.Monad.Trans.Maybe’
instance [safe] Applicative (MaybeT [])
  -- Defined in ‘Control.Monad.Trans.Maybe’
instance [safe] Functor (MaybeT [])
  -- Defined in ‘Control.Monad.Trans.Maybe’
instance [safe] Monad (MaybeT [])
  -- Defined in ‘Control.Monad.Trans.Maybe’
instance [safe] GHC.Base.MonadPlus (MaybeT [])
  -- Defined in ‘Control.Monad.Trans.Maybe’
instance [safe] Data.Functor.Classes.Eq1 (MaybeT [])
  -- Defined in ‘Control.Monad.Trans.Maybe’
instance [safe] Foldable (MaybeT [])
  -- Defined in ‘Control.Monad.Trans.Maybe’
instance [safe] Data.Functor.Classes.Ord1 (MaybeT [])
  -- Defined in ‘Control.Monad.Trans.Maybe’
instance [safe] Data.Functor.Classes.Read1 (MaybeT [])
  -- Defined in ‘Control.Monad.Trans.Maybe’
instance [safe] Data.Functor.Classes.Show1 (MaybeT [])
  -- Defined in ‘Control.Monad.Trans.Maybe’
instance [safe] Traversable (MaybeT [])
  -- Defined in ‘Control.Monad.Trans.Maybe’
instance [safe] MonadFail (MaybeT [])
  -- Defined in ‘Control.Monad.Trans.Maybe’
instance [safe] Control.Monad.Fix.MonadFix (MaybeT [])
  -- Defined in ‘Control.Monad.Trans.Maybe’
instance [safe] Control.Monad.Zip.MonadZip (MaybeT [])
  -- Defined in ‘Control.Monad.Trans.Maybe’
instance [safe] Monad (MaybeT [])
  -- Defined in ‘Control.Monad.Trans.Maybe’
instance [safe] Applicative (MaybeT [])
  -- Defined in ‘Control.Monad.Trans.Maybe’
instance [safe] Functor (MaybeT [])
  -- Defined in ‘Control.Monad.Trans.Maybe’

其中一些实例也可以通过Compose [] Maybe但著名的单子不组成。:instances Compose [] Maybe

>> :instances Compose [] Maybe
instance Alternative (Compose [] Maybe)
  -- Defined in ‘Data.Functor.Compose’
instance Applicative (Compose [] Maybe)
  -- Defined in ‘Data.Functor.Compose’
instance Functor (Compose [] Maybe)
  -- Defined in ‘Data.Functor.Compose’
instance Foldable (Compose [] Maybe)
  -- Defined in ‘Data.Functor.Compose’
instance Eq1 (Compose [] Maybe)
  -- Defined in ‘Data.Functor.Compose’
instance Ord1 (Compose [] Maybe)
  -- Defined in ‘Data.Functor.Compose’
instance Read1 (Compose [] Maybe)
  -- Defined in ‘Data.Functor.Compose’
instance Show1 (Compose [] Maybe)
  -- Defined in ‘Data.Functor.Compose’
instance Traversable (Compose [] Maybe)
  -- Defined in ‘Data.Functor.Compose’
instance Alt (Compose [] Maybe) -- Defined in ‘Data.Functor.Alt’
instance Hashable1 (Compose [] Maybe)
  -- Defined in ‘hashable-1.3.0.0:Data.Hashable.Class’
于 2020-12-16T20:02:16.983 回答