From tgphelps50 at gmail.com Sun Jul 7 15:24:47 2019 From: tgphelps50 at gmail.com (Terry Phelps) Date: Sun, 7 Jul 2019 11:24:47 -0400 Subject: [Haskell-beginners] Question about code I found Message-ID: I found this code on the net somewhere. It compiles and works properly: import qualified Data.ByteString as BS import Text.Printf (printf) toHex :: BS.ByteString -> String toHex bytes = do hex <- BS.unpack bytes printf "%02x" hex I cannot understand the 'do' notation is required, because it seems to be a pure function. I guess there's a monad hiding somewhere that my newbie mind can't see. So, I rewrote the code to remove the 'do stuff': -- BAD import qualified Data.ByteString as BS import Text.Printf (printf) toHex :: BS.ByteString -> String toHex bytes = printf "02x" (BS.unpack bytes) WRONG. Ghci says: xx2.hs:5:15: error: • No instance for (Text.Printf.IsChar GHC.Word.Word8) arising from a use of ‘printf’ • In the expression: printf "02x" (BS.unpack bytes) In an equation for ‘toHex’: toHex bytes = printf "02x" (BS.unpack bytes) | 5 | toHex bytes = printf "02x" (BS.unpack bytes) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Can someone please explain to me: 1. Why does this simple-looking code to convert a bytestring to a string of hex characters require 'do' or equivalent code? 2. What is the specific problem with my version of the code. The error message doesn't mean much to me yet. -------------- next part -------------- An HTML attachment was scrubbed... URL: From fa-ml at ariis.it Sun Jul 7 16:12:45 2019 From: fa-ml at ariis.it (Francesco Ariis) Date: Sun, 7 Jul 2019 18:12:45 +0200 Subject: [Haskell-beginners] Question about code I found In-Reply-To: References: Message-ID: <20190707161245.4pxyi66a5xwr33qs@x60s.casa> Hello Terry On Sun, Jul 07, 2019 at 11:24:47AM -0400, Terry Phelps wrote: > I found this code on the net somewhere. It compiles and works properly: > > import qualified Data.ByteString as BS > import Text.Printf (printf) > toHex :: BS.ByteString -> String > toHex bytes = do > hex <- BS.unpack bytes > printf "%02x" hex > > I cannot understand the 'do' notation is required, because it seems to be a > pure function. I guess there's a monad hiding somewhere that my newbie mind > can't see. `toHex` is pure (non IO), but it has an /effect/. In this case, it takes advantage of the list monad to achieve non-determinism. Specifically, since unpack :: ByteString -> [Word8] printf (which in our case has signature (`String -> Char`) gets called on each of those [Word8]. The result will obviously be [Char], which `String` is an alias of. > So, I rewrote the code to remove the 'do stuff': > > [...] > toHex :: BS.ByteString -> String > toHex bytes = printf "02x" (BS.unpack bytes) A do-less version still is /monadic/, hence it will have >>= or >> or similar somewhere. This works: toHex2 :: BS.ByteString -> String toHex2 bytes = BS.unpack bytes >>= printf "%02x" and follows the reasoning above (feed every every Word8 to `printf "%02x"`). Does this answer your questions? -F From tgphelps50 at gmail.com Sun Jul 7 16:47:19 2019 From: tgphelps50 at gmail.com (Terry Phelps) Date: Sun, 7 Jul 2019 12:47:19 -0400 Subject: [Haskell-beginners] Question about code I found In-Reply-To: <20190707161245.4pxyi66a5xwr33qs@x60s.casa> References: <20190707161245.4pxyi66a5xwr33qs@x60s.casa> Message-ID: I have written enough code in the IO monad to fairly well understand how the 'do' and 'bind' forms work. But I've never seen monadic code that was NOT in the IO monad. Your explanation tells me where to go do more study. Thank you.If I go read the definition of bind in the List monad, it will probably become clear. In the original code, the List monad is completely invisible to my untrained eye, and I was confused. On Sun, Jul 7, 2019 at 12:13 PM Francesco Ariis wrote: > Hello Terry > > On Sun, Jul 07, 2019 at 11:24:47AM -0400, Terry Phelps wrote: > > I found this code on the net somewhere. It compiles and works properly: > > > > import qualified Data.ByteString as BS > > import Text.Printf (printf) > > toHex :: BS.ByteString -> String > > toHex bytes = do > > hex <- BS.unpack bytes > > printf "%02x" hex > > > > I cannot understand the 'do' notation is required, because it seems to > be a > > pure function. I guess there's a monad hiding somewhere that my newbie > mind > > can't see. > > `toHex` is pure (non IO), but it has an /effect/. In this case, it takes > advantage of the list monad to achieve non-determinism. > > Specifically, since > > unpack :: ByteString -> [Word8] > > printf (which in our case has signature (`String -> Char`) gets called > on each of those [Word8]. The result will obviously be [Char], which > `String` is an alias of. > > > So, I rewrote the code to remove the 'do stuff': > > > > [...] > > toHex :: BS.ByteString -> String > > toHex bytes = printf "02x" (BS.unpack bytes) > > A do-less version still is /monadic/, hence it will have >>= or >> > or similar somewhere. This works: > > toHex2 :: BS.ByteString -> String > toHex2 bytes = BS.unpack bytes >>= printf "%02x" > > and follows the reasoning above (feed every every Word8 to > `printf "%02x"`). > > Does this answer your questions? > -F > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > -------------- next part -------------- An HTML attachment was scrubbed... URL: From kc1956 at gmail.com Sun Jul 7 18:16:23 2019 From: kc1956 at gmail.com (KC) Date: Sun, 7 Jul 2019 11:16:23 -0700 Subject: [Haskell-beginners] Question about code I found In-Reply-To: References: <20190707161245.4pxyi66a5xwr33qs@x60s.casa> Message-ID: It's more correct to say the List Monad Is a Monad instance who is a List But people look at you funny In my case Funnier than usual -------------- next part -------------- An HTML attachment was scrubbed... URL: From kc1956 at gmail.com Wed Jul 17 18:48:36 2019 From: kc1956 at gmail.com (KC) Date: Wed, 17 Jul 2019 11:48:36 -0700 Subject: [Haskell-beginners] Question about code I found In-Reply-To: References: <20190707161245.4pxyi66a5xwr33qs@x60s.casa> Message-ID: It's more correct to say the List Monad Is a Monad instance who is a List But people look at you funny In my case Funnier than usual On Sun., Jul. 7, 2019, 9:47 a.m. Terry Phelps, wrote: > I have written enough code in the IO monad to fairly well understand how > the 'do' and 'bind' forms work. But I've never seen monadic code that was > NOT in the IO monad. Your explanation tells me where to go do more study. > Thank you.If I go read the definition of bind in the List monad, it will > probably become clear. In the original code, the List monad is completely > invisible to my untrained eye, and I was confused. > > > On Sun, Jul 7, 2019 at 12:13 PM Francesco Ariis wrote: > >> Hello Terry >> >> On Sun, Jul 07, 2019 at 11:24:47AM -0400, Terry Phelps wrote: >> > I found this code on the net somewhere. It compiles and works properly: >> > >> > import qualified Data.ByteString as BS >> > import Text.Printf (printf) >> > toHex :: BS.ByteString -> String >> > toHex bytes = do >> > hex <- BS.unpack bytes >> > printf "%02x" hex >> > >> > I cannot understand the 'do' notation is required, because it seems to >> be a >> > pure function. I guess there's a monad hiding somewhere that my newbie >> mind >> > can't see. >> >> `toHex` is pure (non IO), but it has an /effect/. In this case, it takes >> advantage of the list monad to achieve non-determinism. >> >> Specifically, since >> >> unpack :: ByteString -> [Word8] >> >> printf (which in our case has signature (`String -> Char`) gets called >> on each of those [Word8]. The result will obviously be [Char], which >> `String` is an alias of. >> >> > So, I rewrote the code to remove the 'do stuff': >> > >> > [...] >> > toHex :: BS.ByteString -> String >> > toHex bytes = printf "02x" (BS.unpack bytes) >> >> A do-less version still is /monadic/, hence it will have >>= or >> >> or similar somewhere. This works: >> >> toHex2 :: BS.ByteString -> String >> toHex2 bytes = BS.unpack bytes >>= printf "%02x" >> >> and follows the reasoning above (feed every every Word8 to >> `printf "%02x"`). >> >> Does this answer your questions? >> -F >> >> _______________________________________________ >> Beginners mailing list >> Beginners at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners >> > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jejones3141 at gmail.com Tue Jul 23 02:29:30 2019 From: jejones3141 at gmail.com (James Jones) Date: Mon, 22 Jul 2019 21:29:30 -0500 Subject: [Haskell-beginners] binding vs. parameter passing Message-ID: One problem in *Programming Haskell from First Principles* confuses me. (So far.) It's one where you start with the declaration and binding i :: Num a => a i = 1 (which of course works because Num a => a is the type of 1) and then change the declaration to i :: a and first try to predict and then see what happens. It fails, with ghci suggesting that you put the Num a => back. That seemed reasonable at first, but then I considered this: - id has type a -> a, and if you try to evaluate id 1 it works without complaint. - In all the work I've done on compilers, parameter passing has effectively been assignment of actual parameters to the corresponding formal parameters. In Haskell, that might mean passing along the appropriate thunk, but the principle is the same, isn't it? So, if I can't bind 1 to i which is declared to have type a, why can I successfully pass 1 to id? -------------- next part -------------- An HTML attachment was scrubbed... URL: From rri at silentyak.com Tue Jul 23 03:44:47 2019 From: rri at silentyak.com (Ramnath R Iyer) Date: Mon, 22 Jul 2019 20:44:47 -0700 Subject: [Haskell-beginners] binding vs. parameter passing In-Reply-To: References: Message-ID: This answer is likely incomplete at best and wrong at worst, but I'll give it a shot. When you have this type declaration: i :: a It means that you are declaring the symbol i that can be slotted into any location that requires an a. It is a task for the compiler to process the overall program specification and infer that a has a particular concrete type. When the program is specified though, the value i has a generic type with no bounds, and the only way to *construct* such a value is to supply a value of type a from somewhere else. The problem here is not that you can't *bind* 1 to i, but that you cannot *construct* any value of type a. A direct analog of this would be - not the application of the id function as you called out - but that you cannot define a function with the following signature, not including bottom: f :: a -> b The reason is that you can't supply a value of type b. I have some experience with Java, and it has a similar constraint that generic types cannot be instantiated. -- RRI On Mon, Jul 22, 2019 at 7:30 PM James Jones wrote: > One problem in *Programming Haskell from First Principles* confuses me. > (So far.) > > It's one where you start with the declaration and binding > > i :: Num a => a > i = 1 > > (which of course works because Num a => a is the type of 1) and then > change the declaration to > > i :: a > > and first try to predict and then see what happens. It fails, with ghci > suggesting that you put the Num a => back. That seemed reasonable at > first, but then I considered this: > > - id has type a -> a, and if you try to evaluate id 1 it works without > complaint. > - In all the work I've done on compilers, parameter passing has > effectively been assignment of actual parameters to the corresponding > formal parameters. In Haskell, that might mean passing along the > appropriate thunk, but the principle is the same, isn't it? > > So, if I can't bind 1 to i which is declared to have type a, why can I > successfully pass 1 to id? > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > -- Ramnath R Iyer -------------- next part -------------- An HTML attachment was scrubbed... URL: From mianorsi at ciencias.unam.mx Tue Jul 23 05:01:06 2019 From: mianorsi at ciencias.unam.mx (=?UTF-8?Q?Miguel_Angel_Ordo=C3=B1ez_Silis?=) Date: Tue, 23 Jul 2019 00:01:06 -0500 Subject: [Haskell-beginners] Stack doesn't find downloaded module Message-ID: Hi! I downloaded the following package https://www.stackage.org/lts-13.29/package/multiset-0.3.4.1 using the following cli (Linux) command: stack install multiset. It was supposedly successfully installed but when I try to import it stack says it couldn't find it ('Could not find module ‘Data.MultiSet’). I've tried reading haskellstack.org's documentation but I've not been able to find a solution. Well, thanks in advance for your help Mike -------------- next part -------------- An HTML attachment was scrubbed... URL: From timmelzer at gmail.com Tue Jul 23 06:03:03 2019 From: timmelzer at gmail.com (Norbert Melzer) Date: Tue, 23 Jul 2019 08:03:03 +0200 Subject: [Haskell-beginners] Stack doesn't find downloaded module In-Reply-To: References: Message-ID: Hello Miguel! On Tue, Jul 23, 2019 at 7:01 AM Miguel Angel Ordoñez Silis < mianorsi at ciencias.unam.mx> wrote: > stack install multiset. > `stack install` is meant to install packages that result in a executable program, not for libraries. > It was supposedly successfully installed but when I try to import it stack > says it couldn't find it ('Could not find module ‘Data.MultiSet’). I've > tried reading haskellstack.org's documentation but I've not been able to > find a solution. > You need to specify `multiset` as a dependency in your `package.yaml` of your project. > > Well, thanks in advance for your help > > Mike > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > -------------- next part -------------- An HTML attachment was scrubbed... URL: