Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 为什么是WrappedMonad和WrappedArrow?_Haskell_Applicative_Newtype - Fatal编程技术网

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)