[英]How does (fmap.fmap) sum Just [1,2,3] type check in Haskell?
[英]How does this Haskell code work? fmap fmap (,) <*> Just . reverse
有人会帮助解释/分解以下代码:
λ> fmap fmap (,) <*> Just . reverse $ "stackoverflow"
Just ("stackoverflow","wolfrevokcats")
如果有人可以引导我完成他们理解这种代码的原理的过程,那就太好了。
让我们尝试解码这种毫无意义的样式混淆:
fmap fmap (,) <*> Just . reverse $ "stackoverflow"
第一步:如何解析? 好吧, $
优先级较低,因此
(fmap fmap (,) <*> Just . reverse) $ "stackoverflow"
另外,我猜中缀<*>
的优先级低于.
(可以使用GHCi中的文档或:i
进行检查)。 所以,我们得到
((fmap fmap (,)) <*> (Just . reverse)) $ "stackoverflow"
让我们Beta减少$
((fmap fmap (,)) <*> (Just . reverse)) "stackoverflow"
因此, <*>
的结果是一个函数。 这意味着我们正在使用(->) a
应用程序。 那里, (<*>) = \\xyz -> xz (yz)
又名Lambda演算的S组合器。 我们可以beta减少:
(\z -> (fmap fmap (,)) z ((Just . reverse) z)) "stackoverflow"
更多beta,可以删除括号:
fmap fmap (,) "stackoverflow" ((Just . reverse) "stackoverflow")
更简化:
fmap fmap (,) "stackoverflow" (Just (reverse "stackoverflow"))
fmap fmap (,) "stackoverflow" (Just "wolfrevokcats")
现在, fmap fmap (,)
部分。 (,)
参数是一个函数,因此这意味着第一个fmap
在(->) a
函数中起作用。 在那里, fmap = (.)
。 所以,这只是对
(.) fmap (,) "stackoverflow" (Just "wolfrevokcats")
(fmap . (,)) "stackoverflow" (Just "wolfrevokcats")
(fmap ((,) "stackoverflow")) (Just "wolfrevokcats")
fmap ((,) "stackoverflow") (Just "wolfrevokcats")
现在, fmap
的第二个参数的类型为Maybe String
,因此fmap
在Maybe
函数中起作用。 在那里, fmap f (Just x) = Just (fx)
。 我们得到
Just (((,) "stackoverflow") "wolfrevokcats")
Just ((,) "stackoverflow" "wolfrevokcats")
Just ("stackoverflow", "wolfrevokcats")
结论:毫无意义的代码通常是毫无意义的。 要解码此代码段,我们必须在头上运行类型推断器,重新调用三个特定的实例(即使它们是非常标准的),并应对优先级。 除了故意混淆之外,没有人可以使用这种样式。 (当然不是招聘难题!)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.