如果我理解正确,a monad只是绑定>>=和return运算符遵循某些规则的实现,这些规则基本上组成了不同返回类型的2个函数.因此,例如,那些是等价的:
putStrLn "What is your name?"
>>= (\_ -> getLine)
>>= (\name -> putStrLn ("Welcome, " ++ name ++ "!"))
(bind (putStrLn "What is your name?")
(bind
(\_ -> getLine)
(\name -> putStrLn ("Welcome, " ++ name ++ "!"))))
Run Code Online (Sandbox Code Playgroud)
但是如果我们强烈地规范化这个表达式,最终的结果就是:
(putStrLn ("Welcome, " ++ getline ++ "!"))
Run Code Online (Sandbox Code Playgroud)
第一个陈述(putStrLn "What is your name?")完全丢失了.此外,getLine看起来像一个没有参数的函数,这是无稽之谈.那么这是如何工作的,以及函数的实际定义是什么?>>=return
J. *_*son 12
你的逻辑错误是你假设某些减少规则不会.特别是,您似乎正在使用
f >>= (\x -> g x) ==== g f
Run Code Online (Sandbox Code Playgroud)
如果这样,那么,monads将是非常愚蠢的:(>>=)只是flip ($).但总的来说,它根本不存在.事实上,它没有成功的原因是为monad提供了一个有趣的机会.
为了进一步探索,这里是一个(>>=) == flip ($)(基本上)持有的monad .
newtype Identity a = Identity { unIdentity :: a }
Run Code Online (Sandbox Code Playgroud)
为了使我们的方程式成功,我们必须使用它Identity a ~ a.显然,这并非严格意义,但让我们假装.特别是,Identity . unIdentity并且unIdentity . Identity都是身份,无操作,我们可以自由地应用Identity或者unIdentity我们喜欢使类型匹配
instance Functor Identity where
fmap f (Identity a) = Identity (f a)
instance Monad Identity where
return a = Identity a -- this is a no-op
ida >>= f = f (unIdentity ida)
Run Code Online (Sandbox Code Playgroud)
现在,我们要特别考察
ida :: Identity a
f :: a -> b
ida >>= Identity . f :: Identity b
===
Identity (f (unIdentity ida)) :: Identity b
Run Code Online (Sandbox Code Playgroud)
如果我们扔掉Identity/ unIdentity噪音,从而产生ida = Identity a一些知识
Identity (f (unIdentity ida)) :: Identity b
===
Identity (f a) :: Identity b
=== ~
f a :: b
Run Code Online (Sandbox Code Playgroud)
因此,虽然(>>=) == flip ($)形成了直觉的某种基础(>>=)......在任何比Identitymonad(和所有其他monad都更有趣)更有趣的情况下,它并不完全正确.
| 归档时间: |
|
| 查看次数: |
121 次 |
| 最近记录: |