Haskell 为什么是WrappedMonad和WrappedArrow?
为什么存在Haskell 为什么是WrappedMonad和WrappedArrow?,haskell,applicative,newtype,Haskell,Applicative,Newtype,为什么存在WrappedMonad和WrappedArrow类型?这是因为Monads不是应用的?假设WrappedArrow存在,实例是否应该 Arrow a => Applicative (Arrow a b) 只需像Applicative现在是Monad的一个超类一样构建到Haskell本身中?对于WrappedMonad来说几乎是这样。我想它基本上已经过时了。但是WrappedArrow更难,因为Arrow类型和Applicative类型有不同的种类,*->*->*与*->*相
WrappedMonad
和WrappedArrow
类型?这是因为Monad
s不是应用的
?假设WrappedArrow
存在,实例是否应该
Arrow a => Applicative (Arrow a b)
只需像
Applicative
现在是Monad
的一个超类一样构建到Haskell本身中?对于WrappedMonad
来说几乎是这样。我想它基本上已经过时了。但是WrappedArrow
更难,因为Arrow
类型和Applicative
类型有不同的种类,*->*->*
与*->*
相比。由于GHC实例解析的工作方式,添加实例(我假设额外的箭头是一个打字错误)
这意味着,没有一个具有两个或多个参数的类型构造函数可以给出一个Applicative
,而不给出一个箭头,这看起来相当激烈
将超类Applicative(ab)=>
添加到Arrow a
的相反选项似乎更合适-除非您不能使用类似b
的有孔类型的超类。这样的超类对于其他东西也很有用,并且已经被建议过很多次了,所以我认为很难很好地实现。我觉得这种新类型的包装器有了新的生命力。让我们假设,无论出于何种原因,我们都希望为一个类型编写Monad
和MonadPlus
实例,然后将它们用于Applicative
和Alternative
:
newtype StT s m a = StT { runStT :: s -> m (a, s) }
deriving Functor
instance Monad m => Monad (StT s m) where
return a = StT $ \s -> return (a, s)
m >>= f = StT $ \s -> m `runStT` s >>= \(a, t) -> f a `runStT` t
instance MonadPlus m => MonadPlus (StT s m) where
mzero = StT $ \_ -> mzero
m `mplus` n = StT $ \s -> (m `runStT` s) `mplus` (n `runStT` s)
通常,我们必须编写样板实例:
instance Monad m => Applicative (StT s m) where
pure = return
(<*>) = ap
instance MonadPlus m => Alternative (StT s m) where
empty = mzero
(<|>) = mplus
请注意,先前存在的派生子句不受影响。另一个很好的触碰是推断出必要的超类约束。也是大多数人认为<代码>箭头< /代码>类设计错误,因此使它成为极其重要的<代码>应用程序类的超类可能不会过好。@ dFuuer-Sub类,而不是超类。它不会直接影响应用程序。然而,在目前的班级制度下,这是不可能的。
instance Monad m => Applicative (StT s m) where
pure = return
(<*>) = ap
instance MonadPlus m => Alternative (StT s m) where
empty = mzero
(<|>) = mplus
newtype StT s m a = StT { runStT :: s -> m (a, s) }
deriving Functor
deriving (Applicative, Alternative) via WrappedMonad (StT s m)