{"componentChunkName":"component---src-lekoarts-gatsby-theme-minimal-blog-core-templates-post-query-tsx","path":"/stream","result":{"data":{"post":{"slug":"/stream","title":"Stream","date":"March 25, 2019","tags":[{"name":"Functional Programming","slug":"functional-programming"}],"description":null,"body":"function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n/* @jsx mdx */\nvar _frontmatter = {\n  \"title\": \"Stream\",\n  \"date\": \"2019-03-25T00:00:00.000Z\",\n  \"tags\": [\"Functional Programming\"],\n  \"excerpt\": \"Infinite data structure\"\n};\n\nvar makeShortcode = function makeShortcode(name) {\n  return function MDXDefaultShortcode(props) {\n    console.warn(\"Component \" + name + \" was not imported, exported, or provided by MDXProvider as global scope\");\n    return mdx(\"div\", props);\n  };\n};\n\nvar layoutProps = {\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n      props = _objectWithoutProperties(_ref, [\"components\"]);\n\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"p\", null, \"Source code from \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://www.cs.mcgill.ca/~prakash/Courses/302/Notes/streams.ml\"\n  }), \"COMP302 course page\"), \". Some helper functions are not shown here.\"), mdx(\"p\", null, \"This post is my attempt to understand the beauty and power of streams.\"), mdx(\"h2\", null, \"Intro\"), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, \"The stream type below allows finite and infinite streams. Finite streams end with an\\nend-of-stream marker that is written as Eos. An infinite stream does not end so it will not have an end-of-stream marker.\")), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-ocaml\"\n  }), \"type 'a stream = Eos | StrCons of 'a * (unit -> 'a stream)\\n\")), mdx(\"p\", null, \"To represent \\u201Cinfinity\\u201D, we need to \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"suspend \"), \" the evaluation or no memory is large enough to hold infinite data. Here, we wrap the stream inside a function, and we \\u201Cwake up\\u201D the stream by applying the function. We can never see the whole stream let alone print it, but we can ask for part of it, as long as this part is finite.\"), mdx(\"h2\", null, \"Examples\"), mdx(\"h3\", null, \"A stream of all ones\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-ocaml\"\n  }), \"let rec ones = StrCons (1, fun () -> ones);;\\n\")), mdx(\"p\", null, \"What is left after you take away the first 1 from infinitely many 1\\u2019s? Infinitely many 1\\u2019s!\"), mdx(\"p\", null, \"So the code is saying: the stream starts with \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"1\"), \", and the rest of the stream also starts with \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"1\"), \", and the rest of the rest\\u2026\"), mdx(\"h3\", null, \"Natural numbers\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-ocaml\"\n  }), \"let rec nums_from (n:int) = StrCons(n, fun () -> nums_from (n + 1));;\\nlet naturals = nums_from 1 (* or 0 if you like *)\\n\")), mdx(\"p\", null, \"Now we have 1,2,3,4,5\\u2026\"), mdx(\"p\", null, \"Take out 1, we get an infinite stream starting from 2, then 3, then\\u2026\"), mdx(\"h3\", null, \"Fibonacci numbers\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-ocaml\"\n  }), \"let fibs =\\n  let rec fibgen (a: int) (b:int) =\\n    StrCons (a, fun () -> fibgen b a+b )\\n  in\\n  fibgen 1 1\\n\")), mdx(\"p\", null, \"Below is a great picture that I found on \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://stackoverflow.com/a/37243672/9407207\"\n  }), \"stackoverflow\"), \" for the famous one-liner in Haskell:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-haskell\"\n  }), \"fib = 1 : 1 : (zipWith (+) fib (tail fib))\\n\")), mdx(\"p\", null, mdx(\"img\", _extends({\n    parentName: \"p\"\n  }, {\n    \"src\": \"https://cdn.jsdelivr.net/gh/Deerhound579/image-hosting/img/VheDF.png\",\n    \"alt\": \"Visualization\"\n  }))), mdx(\"h3\", null, \"Partial sum\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-ocaml\"\n  }), \"let rec partialsum (s: int stream) =\\n     match s with\\n     | Eos -> Eos\\n     | StrCons (h, t) -> StrCons (h, fun () -> zipWith (+) (t()) partialsum s)\\n     (*\\n     * t() is necessary because t is fun() -> 'a stream\\n     * We need to wake it up. It is taking the tail of the input stream\\n     *)\\n\")), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-ocaml\"\n  }), \"partialsum ones:\\n(* pseudocode *)\\n(* For convenience, I'll use shorthand for those functions *)\\nzw = zipWith (+) (a: 'a stream) (b: 'b stream)\\nps = partialsum = [1, (zw [1,..] ps)]\\n\\n(* Try to visualize this *)\\nps = [1, (zw [1,..] ps)]\\n\\n(* ps [1,1,..] =\\n * [1, 1+1, 1+2, 1+3 ]\\n * Translate it into human language:\\n * Take the next element in the input stream, add it to the last partial sum\\n * That is, ps[i] = input[i] + ps[i-1], where ps[i] is the i-th partial sum\\n *)\\n[ 1, (zw [1,..] ps) ]\\n[ 1, zw [1,..] ([1, (zw [1,..] ps)]) ]\\n[ 1, 1+1, zw [1,..] (zw [1,..] ps) ]\\n[ 1, 2, zw [1,..] (zw [1,..] [1, (zw [1,..] ps) ]]\\n[ 1, 2, zw [1,..] [2, (zw [1,..] (zw [1,..] ps) ]]\\n[ 1, 2, 3 zw ..]\\n\")));\n}\n;\nMDXContent.isMDXComponent = true;","excerpt":"Infinite data structure","banner":null}},"pageContext":{"slug":"/stream"}}}