如果我有两个单子m和n,和n是穿越,我一定有复合m-over- n单子?
更正式的,这就是我的想法:
import Control.Monad
import Data.Functor.Compose
prebind :: (Monad m, Monad n) =>
m (n a) -> (a -> m (n b)) -> m (n (m (n b)))
mnx `prebind` f = do nx <- mnx
return $ do x <- nx
return $ f x
instance (Monad m, Monad n, Traversable n) => Monad (Compose m n) where
return = Compose . return . return
Compose mnmnx >>= f …Run Code Online (Sandbox Code Playgroud) 下面是几个简单的函数:
f1 :: () -> ()
f1 () = ()
f2 :: a -> a
f2 a = a
f3 :: a -> (a, a)
f3 a = (a, a)
f4 :: (a, b) -> a
f4 (a, b) = a
Run Code Online (Sandbox Code Playgroud)
所有的f1,f2以及f3能够接受()为输入。另一方面,当然f4不能接受();f4 ()是类型错误。
是否有可能TYPE-理论上刻画了什么f1,f2以及f3有什么共同点?具体而言,是有可能定义一个acceptsUnit函数,以使得acceptsUnit f1,acceptsUnit f2和acceptsUnit f3是公类型的,但acceptsUnit f4是一种类型的错误-和不具有其他的效果?
下面完成了部分工作,但将其输入单态化(在 Haskell …
用于环境共享和非确定性的规范"Monad实例"如下(使用伪Haskell,因为Haskell Data.Set当然不是monadic):
eta :: a -> r -> {a} -- '{a}' means the type of a set of a's
eta x = \r -> {x}
bind :: (r -> {a}) -> (a -> r -> {b}) -> r -> {b}
m `bind` f = \r -> {v | x ? m r, v ? f x r}
Run Code Online (Sandbox Code Playgroud)
通常,当尝试将像Powerset(List,Writer等)的"容器"monad与第二个monad m(这里,粗略地,Reader)组合时,一个'包裹' m在容器monad周围,如上所述.
那么,我想知道以下潜在的Powerset-over-Reader规范:
eta' :: a -> {r -> a}
eta' x = {\r -> x}
bind' :: {r …Run Code Online (Sandbox Code Playgroud) 通常在Haskell我们定义Monad来讲小号return和>>=.有时分解>>=成fmap和方便join.Monad一旦你习惯了这两种配方的法律是众所周知的,并且相当直观.
根据仿Applicative函数,还有另一种定义monad的方法:
class Applicative f => MyMonad f where
myJoin :: f (f a) -> f a
Run Code Online (Sandbox Code Playgroud)
我想知道这种配方的法律.显然,我们可以调整fmap+ join法则,如下所示(我不确定这些名称是否特别贴切,但是很好):
myJoin . myJoin = myJoin . (pure myJoin <*>) ('Associativity')
myJoin . pure = myJoin . (pure pure <*>) = id ('Identity')
Run Code Online (Sandbox Code Playgroud)
显然,这些条件足以对pure,(<*>)和myJoin以形成单子(在这个意义上,它们保证m `myBind` f = myJoin (pure f <*> m)将成为一个行为良好>>= …
我对这里描述的用于确定伴随仿函数的monad变换器的结构很感兴趣.这里有一些代码总结了基本思想:
{-# LANGUAGE MultiParamTypeClasses #-}
import Control.Monad
newtype Three g f m a = Three { getThree :: g (m (f a)) }
class (Functor f, Functor g) => Adjoint f g where
counit :: f (g a) -> a
unit :: a -> g (f a)
instance (Adjoint f g, Monad m) => Monad (Three g f m) where
return = Three . fmap return . unit
m >>= f = Three $ fmap (>>= counit . …Run Code Online (Sandbox Code Playgroud) 定义索引 monad a la Atkey的常用方法是:
class IxMonad m where
ireturn :: a -> m i i a
ibind :: m i j a -> (a -> m j k b) -> m i k b
Run Code Online (Sandbox Code Playgroud)
另一种方法可以在McBride的工作中找到(他也在这里讨论过):
type f :-> g = forall i. f i -> g i
class MonadIx (m :: (state -> *) -> (state -> *)) where
returnIx :: f :-> m f
flipBindIx :: (f :-> m g) -> (m f …Run Code Online (Sandbox Code Playgroud) 一个常见的例子用于说明monad是如何从伴随函子出现的State.这是一个很好的例子的原因之一是两个伴随函子,(->) r并且(,) r都是Hask上的endofunctors.其他规范的monad涉及进出Hask的伴随函子(例如,[]和Maybe),这使得对于了解Haskell但在类别理论中具有较少背景的人更难理解.
Hask上有伴随endofunctors出现的其他常见monad吗?(显然Identitymonad是一个这样的案例,但不是一个非常有趣的案例.)
haskell ×7
monads ×6
state-monad ×2
applicative ×1
polymorphism ×1
reader-monad ×1
system-f ×1
type-theory ×1