From 6533333da14ccfa435012d25cc1d351bd9c31b93 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Samuel=20G=C3=A9lineau?= <gelisam+github@gmail.com>
Date: Sun, 15 Feb 2015 13:55:38 -0500
Subject: [PATCH] Simpler examples for type inference

The previous JSON examples required a bit too much prior understanding
of Haskell for a front-page example.
---
 src/HL/View/Home/Features.hs | 64 +++++++++++++++++++-----------------
 1 file changed, 33 insertions(+), 31 deletions(-)

diff --git a/src/HL/View/Home/Features.hs b/src/HL/View/Home/Features.hs
index bd6968a..ada4780 100644
--- a/src/HL/View/Home/Features.hs
+++ b/src/HL/View/Home/Features.hs
@@ -116,39 +116,41 @@ inference :: Html ()
 inference =
   do h2_ "Type inference"
      p_ "You don't have to explicitly write out every type in a Haskell program. \
-       \Types will be inferred by unifying every type bidirectionally. However, you \
-       \can write out types if you choose, or ask the compiler to write them for you \
-       \for handy documentation."
+       \Types will be inferred by unifying every type bidirectionally. This means \
+       \you can write a definition and ask the compiler to infer its type for \
+       \you, and you can also write a type signature and ask the compiler to help \
+       \you with the implementation."
      p_ [class_ "expand"] (a_ "Click to expand")
      div_ [class_ "expandable"] $ do
-       p_ "This example has a type signature for every binding:"
-       haskellPre "main :: IO ()\n\
-                  \main = do line :: String <- getLine\n\
-                  \          print (parseDigit line)\n\
-                  \  where parseDigit :: String -> Maybe Int\n\
-                  \        parseDigit ((c :: Char) : _) =\n\
-                  \          if isDigit c\n\
-                  \             then Just (ord c - ord '0')\n\
-                  \             else Nothing"
-       p_ "But you can just write:"
-       haskellPre "main = do line <- getLine\n\
-                  \          print (parseDigit line)\n\
-                  \  where parseDigit (c : _) =\n\
-                  \          if isDigit c\n\
-                  \             then Just (ord c - ord '0')\n\
-                  \             else Nothing"
-       p_ "You can also use inference to avoid wasting time explaining \
-         \what you want:"
-       haskellPre "do ss <- decode \"[\\\"Hello!\\\",\\\"World!\\\"]\"\n\
-                  \   is <- decode \"[1,2,3]\"\n\
-                  \   return (zipWith (\\s i -> s ++ \" \" ++ show (i + 5)) ss is)\n\
-                  \ => Just [\"Hello! 6\",\"World! 7\"]"
-       p_ "Types give a parser specification for free, the following \
-         \input is not accepted:"
-       haskellPre "do ss <- decode \"[1,2,3]\"\n\
-                  \   is <- decode \"[null,null,null]\"\n\
-                  \   return (zipWith (\\s i -> s ++ \" \" ++ show (i + 5)) ss is)\n\
-                  \ => Nothing"
+       p_ "For example, consider the following definition:"
+       haskellPre "mySnd (x, y) = y"
+       p_ (do "If you type "
+              code_ ":t mySnd"
+              " in the "
+              code_ "ghci"
+              " interactive environment, the compiler will tell you that its type is "
+              code_ "(t, t1) -> t1"
+              ". Alternatively, we can write the type signature ourselves and omit \
+              \part of the implementation:")
+       haskellPre "mySnd :: (a, b) -> b\n\
+                  \mySnd (x, y) = _hole"
+       p_ (do "Here, the compiler will tell us that we need a value of type "
+              code_ "b"
+              " to fill the hole, and that among the values which are in scope, "
+              code_ "y"
+              " is the only one which has the required type.")
+       p_ (do "Haskell can also use types to infer which of several implementations \
+              \you want. Here, the two calls to "
+              code_ "read"
+              " both receive a "
+              code_ "String"
+              " argument, but are using different implementations because they \
+              \need to return different types.")
+       haskellPre "parsedValues :: (Int, Bool)\n\
+                  \parsedValues = (read s1, read s2)\n\
+                  \  where\n\
+                  \    s1, s2 :: String\n\
+                  \    (s1, s2) = break (== ' ') \"42 True\""
 
 lazy :: Html ()
 lazy =