{"id":18647,"date":"2017-08-16T13:36:43","date_gmt":"2017-08-16T17:36:43","guid":{"rendered":"https:\/\/mjtsai.com\/blog\/?p=18647"},"modified":"2017-08-16T13:36:43","modified_gmt":"2017-08-16T17:36:43","slug":"an-aside-about-flatmap-and-monads","status":"publish","type":"post","link":"https:\/\/mjtsai.com\/blog\/2017\/08\/16\/an-aside-about-flatmap-and-monads\/","title":{"rendered":"An Aside About flatMap and Monads"},"content":{"rendered":"<p><a href=\"https:\/\/www.cocoawithlove.com\/blog\/an-aside-about-flatmap-and-monads.html\">Matt Gallagher<\/a>:<\/p>\n<blockquote cite=\"https:\/\/www.cocoawithlove.com\/blog\/an-aside-about-flatmap-and-monads.html\">\n<p>The way Haskell deals with these problems is that you can interact with these services freely but you never get access to the result. Instead, you get a container (an IO monad) that you can never unwrap. If you never unwrap a container containing side effects, then you remain free from the impact of those side effects &#x2013; your actions remain the same regardless of whether the container holds a fully parsed data structure or a file-not-found error.<\/p>\n<p>How can you handle a container that you can never unwrap? With transformations like <code>map<\/code>, of course. A <code>map<\/code> transformation in Haskell is effectively your code telling the runtime system: please look inside the container for me and should the container contain a value, then apply this function.<\/p>\n<p>[&#8230;]<\/p>\n<p>A true monad transformation requires that all the container types involved be the same kind - a restriction which is not enforced, here. This [Swift] <code>flatMap<\/code> function operates on any <code>Sequence<\/code>, produces a second <code>Sequence<\/code> kind that isn&rsquo;t necessarily the same as the first and returns the concatenation as an <code>Array<\/code>. This function is only a monad if both the <code>Sequence<\/code> arguments are <code>Array<\/code>. All other usage of this function results in not-a-monad.<\/p>\n<p>[&#8230;]<\/p>\n<p>For the purpose of <code>flatMap<\/code>, it appears that <code>Optional<\/code> is treated as a collection and is permitted to be mixed and matched like any other collection. This bothers some people but personally, I think it makes sense. I&rsquo;ve always been more concerned by the naming problem caused by the fact that <code>flatMap(x)<\/code> needs to be read backwards. The function is really <code>flatten(map(x))<\/code> &#x2013; a map and then a flatten &#x2013; which would be more correctly transcribed as <code>mapFlatten<\/code>.<\/p>\n<\/blockquote>","protected":false},"excerpt":{"rendered":"<p>Matt Gallagher: The way Haskell deals with these problems is that you can interact with these services freely but you never get access to the result. Instead, you get a container (an IO monad) that you can never unwrap. If you never unwrap a container containing side effects, then you remain free from the impact [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"apple_news_api_created_at":"","apple_news_api_id":"","apple_news_api_modified_at":"","apple_news_api_revision":"","apple_news_api_share_url":"","apple_news_coverimage":0,"apple_news_coverimage_caption":"","apple_news_is_hidden":false,"apple_news_is_paid":false,"apple_news_is_preview":false,"apple_news_is_sponsored":false,"apple_news_maturity_rating":"","apple_news_metadata":"\"\"","apple_news_pullquote":"","apple_news_pullquote_position":"","apple_news_slug":"","apple_news_sections":"\"\"","apple_news_suppress_video_url":false,"apple_news_use_image_component":false,"footnotes":""},"categories":[4],"tags":[361,71,901],"class_list":["post-18647","post","type-post","status-publish","format-standard","hentry","category-programming-category","tag-haskell","tag-programming","tag-swift-programming-language"],"apple_news_notices":[],"_links":{"self":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/18647","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/comments?post=18647"}],"version-history":[{"count":1,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/18647\/revisions"}],"predecessor-version":[{"id":18648,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/18647\/revisions\/18648"}],"wp:attachment":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/media?parent=18647"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/categories?post=18647"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/tags?post=18647"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}