这个类似monad的函数式编程模式的名称是什么?

Owe*_*wen 20 monads haskell design-patterns functional-programming

我偶尔在代码中遇到一个类似于monad的模式,但不会保持一致的类型>>=.

这是我能提出的最简单的例子:

(首先是一些类型级的布尔值:

data TyT = TyT
data TyF = TyF

class TyOr a b c | a b -> c

instance TyOr TyF TyF TyF
-- rest similarly
Run Code Online (Sandbox Code Playgroud)

)

现在这里是我们的"monad"类型构造函数:

data Marked p a = Marked a
    deriving (Show)
Run Code Online (Sandbox Code Playgroud)

对于给定的p,Marked p是一个* -> *非常像mmonad中的行为,但是当我们定义"bind"时,就像接下来发生的那样:

(>>%) :: (TyOr p q r) => Marked p a -> (a -> Marked q b) -> Marked r b
(Marked x) >>% f = Marked y where Marked y = f x
Run Code Online (Sandbox Code Playgroud)

这里的不同之处在于,结果>>%具有与参数不同的类型构造函数.除此之外,它基本上是一个单子.

我们可以像这样使用它:

a :: Marked TyF Int
a = Marked 5

f :: Int -> Marked TyT Int
f x = Marked (x + 1)

ghci> a >>% f
Marked 6

ghci> :t a >>% f
a >>% f :: Marked TyT Int
Run Code Online (Sandbox Code Playgroud)

(这是受到outis的观察的启发,即Python的"with"不能成为monad,因为它改变了类型,但我也以其他(更简单的)方式看到它).

C. *_*ann 10

嗯,它在某种意义上与monad密切相关,只是与Monad类型类不兼容.特别是,我们可以注意到以下相似之处:

  • Monoids具有关联操作,其身份在一致类型的值上定义:mappend :: a -> a -> amempty :: a.

  • Monads具有在类型构造函数上定义的标识的关联操作,例如:join :: m (m a) -> m areturn :: a -> m a.

  • 函数 - 实际上,类别中的箭头 - 具有关联操作和标识,但关联操作由类别的对象索引,这里的意思是"类型":(.) :: arr b c -> arr a b -> arr a cid :: arr a a.

......那么join按类型索引的monad 是什么?嗯.

您可能会发现一些有趣的参考资料,探索相关概念:


post scriptum - 你在对这个问题的评论中这样说:

你是对的.我实际上想要修复它更像monad,尽管我不是真的"使用"monad.我会编辑它.虽然我会对Applicatives提出或多或少相同的问题.

实际上,限制Applicative变化的事情非常重要!a -> Marked p b和之间的区别在于Marked p (a -> b),在前者中,Marked p结构的属性可以取决于a参数; 而在后者中,标记与函数的参数无关.独立性意味着两者可以分开处理,这大大简化了事情; 注意到任何类型的值都是类型a函数的同构() -> a,你可以Arrow用一种简单的方式把它变成某种双层版本.

另一方面,涉及Monad意味着函数和标记上下文之间存在某种程度的交错,这使得问题变得复杂,原因类似于在该问题的答案中讨论的原因.