在思考如何推广monad时,我想出了一个仿函数F的以下属性:
inject :: (a -> F b) -> F(a -> b)
Run Code Online (Sandbox Code Playgroud)
- 这应该是a和b中的自然变换.
如果没有更好的名称,如果存在上面显示的自然变换,我将函数F称为可绑定inject.
主要问题是,这个属性是否已经知道并且有一个名称,它是如何与仿函数的其他众所周知的属性相关的(例如,应用,monadic,尖头,可遍历等)
名称"可绑定"的动机来自以下考虑:假设M是monad而F是"可绑定"仿函数.然后有一个具有以下自然态射:
fbind :: M a -> (a -> F(M b)) -> F(M b)
Run Code Online (Sandbox Code Playgroud)
这类似于monadic"bind",
bind :: M a -> (a -> M b) -> M b
Run Code Online (Sandbox Code Playgroud)
除了结果用仿函数F装饰.
背后的想法fbind是,广义的monadic操作不仅可以产生单个结果M b,而且可以产生这种结果的"函数"F.我想表达一个monadic操作产生几个"计算线"而不仅仅是一个的情况; 每个"计算链"再次成为一元计算.
注意,每个仿函数F都具有态射
eject :: F(a -> b) -> a -> F b
Run Code Online (Sandbox Code Playgroud)
这与"注入"相反.但并非每个仿函数F都有"注入".
具有"注入"的仿函数的示例:F t = (t,t,t) 或者F t = c -> (t,t)其中c是常量类型.F t = cFunctor(常量仿函数)或 …
monads haskell functional-programming functor category-theory
对于函数 monad,我发现(<*>)和(>>=)/(=<<)有两个非常相似的类型。特别是,(=<<)使相似性更加明显:
(<*>) :: (r -> a -> b) -> (r -> a) -> (r -> b)
(=<<) :: (a -> r -> b) -> (r -> a) -> (r -> b)
Run Code Online (Sandbox Code Playgroud)
所以它就像(<*>)和(>>=)/(=<<)取一个二元函数和一个一元函数,并限制前者的两个参数之一通过后者从另一个参数中确定。毕竟,我们知道对于函数 applicative/monad,
f <*> g = \x -> f x (g x)
f =<< g = \x -> f (g x) x
Run Code Online (Sandbox Code Playgroud)
它们看起来非常相似(或者对称,如果你愿意的话),我不禁想到标题中的问题。
关于 monad 比应用函子“更强大”,在LYAH 的For a few Monads …
monads haskell functional-programming applicative combinatory-logic
a -> m bfrom to函数m (a -> b)在编程中很少出现,但可以在 Reader monad 中制作。以下代码是暂定的实现。这样的图书馆存在吗?
class Monad m => MonadShift m where
shift :: (a -> m b) -> m (a -> b)
instance MonadShift Identity where
shift f = Identity (\x -> runIdentity (f x))
instance MonadShift m => MonadShift (ReaderT r m) where
shift f = ReaderT (\r -> shift (\x -> runReaderT (f x) r))
Run Code Online (Sandbox Code Playgroud) 阅读http://learnyouahaskell.com/functors-applicative-functors-and-monoids#applicative-functors之后,我可以提供一个将函数用作应用函子的示例:
比方说res是4个参数和功能fa,fb,fc,fd是采取单一参数的所有功能。然后,如果我没记错的话,此适用表达式:
f <$> fa <*> fb <*> fc <*> fd $ x
Run Code Online (Sandbox Code Playgroud)
与此非特殊表达式的含义相同:
f (fa x) (fb x) (fc x) (fd x)
Run Code Online (Sandbox Code Playgroud)
啊。我花了很多时间来理解为什么会这样,但是-在一张纸上放着我的笔记的帮助下-我应该能够证明这一点。
然后,我阅读了http://learnyouahaskell.com/for-a-few-monads-more#reader。我们再次以monadic语法重新介绍了这些内容:
do
a <- fa
b <- fb
c <- fc
d <- fd
return (f a b c d)
Run Code Online (Sandbox Code Playgroud)
尽管我需要另一张A4笔记来证明这一点,但我现在非常有信心,这也意味着相同:
f (fa x) (fb x) (fc x) (fd x)
Run Code Online (Sandbox Code Playgroud)
我糊涂了。为什么?这有什么用?
或者,更准确地说:在我看来,这只是复制了函数的功能作为应用程序,但语法更为冗长。
因此,您能否举一个例子,说明Reader monad能否像应用程序那样起作用?
其实,我也想问问有什么用任何这些二:应用性功能或阅读器单子-因为同时能够同样的论点适用于四种功能(fa,fb,fc,fd …
Haskell aviary 组合器列出(=<<)为:
(a -> r -> b) -> (r -> a) -> r -> b
Run Code Online (Sandbox Code Playgroud)
有官方鸟名吗?或者它可以通过预先存在的派生出来吗?
一旦我问了这个问题,这个问题就被正确地标记为与另一个问题重复。
现在我很好奇,一对同构类型的 monad 实例是否有任何已知的用例?
以下是它的实例:
data Pair a = Pair a a deriving Show
instance Functor Pair where
fmap f (Pair a b) = Pair (f a) (f b)
instance Applicative Pair where
pure a = Pair a a
Pair f g <*> Pair x y = Pair (f x) (g y)
instance Monad Pair where
m >>= f = joinPair (f <$> m)
joinPair :: Pair (Pair a) -> Pair a
joinPair (Pair (Pair x …Run Code Online (Sandbox Code Playgroud) 我一直试图掌握读者monad并且遇到了这个教程.在其中,作者提出了这个例子:
example2 :: String -> String
example2 context = runReader (greet "James" >>= end) context
where
greet :: String -> Reader String String
greet name = do
greeting <- ask
return $ greeting ++ ", " ++ name
end :: String -> Reader String String
end input = do
isHello <- asks (== "Hello")
return $ input ++ if isHello then "!" else "."
Run Code Online (Sandbox Code Playgroud)
我知道这是一个显示机制的简单例子,但我想弄清楚为什么它比做类似的东西更好:
example3 :: String -> String
example3 = end <*> (greet "James")
where
greet …Run Code Online (Sandbox Code Playgroud)