100*_*000 15 monads haskell functor applicative
这两个表达
y >> pure x
liftM (const x) y
Run Code Online (Sandbox Code Playgroud)
在Haskell中具有相同的类型签名。我很好奇它们是否相等,但是我既不能提供事实的证明,也不能提出反驳的例子。
如果我们重写这两个表达式以便消除x,y则问题就变成以下两个函数是否等效
flip (>>) . pure
liftM . const
Run Code Online (Sandbox Code Playgroud)
请注意,这两个函数都具有type Monad m => a -> m b -> m a。
我使用了Haskell为monad,applicatives和functor给出的定律,将这两个陈述转换为各种等效形式,但是我无法在两者之间产生一系列等效关系。
例如我发现y >> pure x可以重写如下
y >>= const (pure x)
y *> pure x
(id <$ y) <*> pure x
fmap (const id) y <*> pure x
Run Code Online (Sandbox Code Playgroud)
并且liftM (const x) y可以如下重写
fmap (const x) y
pure (const x) <*> y
Run Code Online (Sandbox Code Playgroud)
这些对我来说并没有必然是等同的,但我无法想到在任何情况下它们都不等同。
Dan*_*ner 15
另一个答案最终到达了那儿,但是走了一条漫长的路。所有这一切实际需要是的定义liftM,const以及一个单子法:m1 >> m2和m1 >>= \_ -> m2语义上必须相同。(实际上,这是的默认实现(>>),很少会覆盖它。)然后:
liftM (const x) y
= { definition of liftM* }
y >>= \z -> pure (const x z)
= { definition of const }
y >>= \z -> pure x
= { monad law }
y >> pure x
Run Code Online (Sandbox Code Playgroud)
*好吧,好吧,这样的实际定义liftM的用途return,而不是pure。随你。
Sri*_*aic 12
让我们从开始flip (>>) . pure,这是x >> pure y您提供的无意义版本:
flip (>>) . pure
Run Code Online (Sandbox Code Playgroud)
这是一个情况flip (>>)就是(=<<) . const这样,我们也可以重写此为:
((=<<) . const) . pure
Run Code Online (Sandbox Code Playgroud)
由于函数组合((.))是关联的,我们可以这样写:
(=<<) . (const . pure)
Run Code Online (Sandbox Code Playgroud)
现在我们要重写const . pure。我们可以注意到,const就pure在上(a ->),这意味着由于pure . pureis fmap pure . pure,const . pureis (.) pure . const,((.)是fmap函子的(a ->))。
(=<<) . ((.) pure . const)
Run Code Online (Sandbox Code Playgroud)
现在,我们再次关联:
((=<<) . (.) pure) . const
Run Code Online (Sandbox Code Playgroud)
((=<<) . (.) pure)是liftM1的定义,因此我们可以替代:
liftM . const
Run Code Online (Sandbox Code Playgroud)
这就是目标。两者是相同的。
1:的定义liftM就是liftM f m1 = do { x1 <- m1; return (f x1) },我们可以desugar的do进入liftM f m1 = m1 >>= return . f。我们可以翻转(>>=)for liftM f m1 = return . f =<< m1并m1消除以获得liftM f = (return . f =<<)一点毫无意义的魔法,我们得到liftM = (=<<) . (.) return
| 归档时间: |
|
| 查看次数: |
746 次 |
| 最近记录: |