Send Beginners mailing list submissions to beginners@haskell.org To subscribe or unsubscribe via the World Wide Web, visit http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners or, via email, send a message with subject or body 'help' to beginners-requ...@haskell.org
You can reach the person managing the list at beginners-ow...@haskell.org When replying, please edit your Subject line so it is more specific than "Re: Contents of Beginners digest..." Today's Topics: 1. Re: Understanding Monads: Help with 20 Intermediate Haskell Exercises (Imants Cekusins) 2. Re: Understanding Monads: Help with 20 Intermediate Haskell Exercises (Gesh) 3. ANNOUNCE: Haskell Communities and Activities Report (30th ed., May 2016) (Mihai Maruseac) ---------------------------------------------------------------------- Message: 1 Date: Wed, 18 May 2016 17:58:13 +0200 From: Imants Cekusins <ima...@gmail.com> To: The Haskell-Beginners Mailing List - Discussion of primarily beginner-level topics related to Haskell <beginners@haskell.org> Subject: Re: [Haskell-beginners] Understanding Monads: Help with 20 Intermediate Haskell Exercises Message-ID: <cap1qinarycpepowe1mxzmnp2nz0wardwcmq6demnwmokfi4...@mail.gmail.com> Content-Type: text/plain; charset="utf-8" Hello Tushar, maybe this makes it look a bit clearer: class Misty m where banana:: (f -> m b) -> m f -> m b furry':: (a -> b) -> m a -> m b apple::Misty m => m a -> m (a -> b) -> m b apple ma mf = banana (\f -> furry' f ma) mf in a word: 'a' in banana may be a function f = a -> b ? -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.haskell.org/pipermail/beginners/attachments/20160518/edd99b3d/attachment-0001.html> ------------------------------ Message: 2 Date: Wed, 18 May 2016 20:10:08 +0300 From: Gesh <g...@gesh.uni.cx> To: beginners@haskell.org Subject: Re: [Haskell-beginners] Understanding Monads: Help with 20 Intermediate Haskell Exercises Message-ID: <f0b25fd3-387a-0e31-cd06-5daecedc4...@gesh.uni.cx> Content-Type: text/plain; charset=UTF-8; format=flowed On 2016-05-18 13:24, Tushar Tyagi wrote: > Hi, > > In order to wrap my head around Applicatives and Monads, I started > doing the > exercises at > http://blog.tmorris.net/posts/20-intermediate-haskell-exercises/ > > The main class being used for the questions is: > |class Misty m where banana :: (a -> m b) -> m a -> m b unicorn :: a -> > m afurry' :: (a -> b) -> m a -> m b Question #13 asks to create the > following function: ||apple :: (Misty m) => m a -> m (a -> b) -> m b |||After > thinking for around an hour for this, I could not crack it and > tried looking at other people's solutions, two of which are: | |apple > = banana . flip furry' apple ma mab = banana (\ab -> furry' ab ma) mab || |Note that these two definitions are equivalent, as we may calculate: > banana . flip furry' > = banana . (\x y -> furry' y x) > = \z -> banana ((\x y -> furry' y x) z) > = \z -> banana (\y -> furry' y z) > = \ma -> banana (\ab -> furry' ab ma) So far, we haven't made use of anything about banana and furry' - this calculation works for any pair of functions such that the expression typechecks. However, we only know that the expression has type (a -> b) for some a,b. Suppose we assume that b is a type of form (c -> d), giving the entire expression the type (a -> c -> d). Then we may write: > = \ma mab -> banana (\ab -> furry' ab ma) mab To see this point in another context, consider the function `id x = x`. If we assume that `x :: a -> b` (e.g. by writing the type signature `id :: (a -> b) -> (a -> b)`), then we may also write `id f = \x -> f x`. In our case, we may make this assumption, since banana accepts two arguments. (More formally, `banana :: a -> b -> c` for some a,b,c). | > || > |I also tried hoogle to see what this function is in the real world, > and the underlying implementation in the source code. Turns out, one > of the applicatives uses this flip technique (monads use a different > one): |(<**>) = liftA2 (flip ($)) > |Although the code compiles with the solutions, I am still not able to > wrap my head around them. | This is a good idea in general if you're stuck with these questions. However, it does come with the risk of mistakenly thinking you've found the correct real-world code. This is the case here. Whereas (<**>) and apple have the same type, they have different semantics. Instead, you want `flip ap`. > ap :: (Monad m) => m (a -> b) -> m a -> m b > ap m1 m2 = do { x1 <- m1; x2 <- m2; return (x1 x2) } It is left as an exercise to the reader to show that, by the desugaring of do-notation as specified in section 3.14 of the Haskell 98 report, we have the following equivalent definition of `apple=flip ap`: > apple mx mf = mf >>= \f -> mx >>= \x -> return (f x) We may then use the definitions: > liftM :: (Monad m) => (a1 -> r) -> m a1 -> m r > liftM f m1 = do { x1 <- m1; return (f x1) } > (=<<) :: Monad m => (a -> m b) -> m a -> m b > f =<< x = x >>= f to obtain: > apple mx mf = mf >>= \f -> mx >>= \x -> return (f x) > = mf >>= \f -> liftM f mx > = flip liftM mx =<< mf Some pointfreeifying gives: > \mx mf -> flip liftM mx =<< mf > = \mx mf -> (=<<) (flip liftM mx) mf > = \mx -> (=<<) (flip liftM mx) > = (=<<) . flip liftM Notice that (=<<) and banana have the same type, and so do liftM and furry', to realize this is the original definition you gave. In contrast, <**> would reduce to (exercise): > mx <**> mf = mx >>= \x -> mf >>= \f -> return (f x) Note that the order of the `mx >>=...` and `mf >>=...` parts is reversed. In general, these might not commute. For example, if `mx=print 1`, `mf=print 2 >>= \_ -> return id`, we'd have that `mx `apple` mf` prints first 2, then 1, whereas `mx <**> mf` prints first 1, then 2. > |For instance, from what I understand from composition, the output of > one function becomes the input of the next one. But the input and > outputs of these functions vary: banana :: Misty m => (a -> m b) -> m > a -> m b flip furry' :: Misty m => m a -> (a -> b) -> m b banana . > flip furry' :: Misty m => m a -> m (a -> b) -> m b | > |I am thinking that the entire `(a -> b) -> m b` in flip furry' ||is being > sent to banana as the first argument: (a -> m b), but what > happens after that? | |This is correct. To be completely formal, this is how you show that `banana . flip furry'` has the desired type. (cf. TaPL by Benjamin Pierce) (Note that we drop the Misty m contexts for convenience): > flip :: (a -> b -> c) -> b -> a -> c > -------------------------------------- (T-ARR-ASSOC) > flip :: (a -> b -> c) -> (b -> a -> c) > furry' :: (a -> b) -> m a -> m b > ----------------------------------------------------- (T-APP) > flip furry' :: m a -> (a -> b) -> m b > --------------------------------------- (T-ARR-ASSOC) > flip furry' :: m a -> ((a -> b) -> m b) > > banana :: (a -> m b) -> m a -> m b > ------------------------------------ (T-ARR-ASSOC) > banana :: (a -> m b) -> (m a -> m b) > > (.) :: (b -> c) -> (a -> b) -> a -> c > --------------------------------------------------------------------- (T-INST) > (.) :: ((a -> m b) -> (m a -> m b)) -> (d -> (a -> m b)) -> d -> (m a -> m b) > banana :: (a -> m b) -> (m a -> m b) > ------------------------------------------------- (T-APP) > (.) banana :: (d -> (a -> m b)) -> d -> (m a -> m b) > --------------------------------------------------------------------- (T-INST) > (.) banana :: (m a -> ((a -> b) -> m b)) -> m a -> (m (a -> b) -> m b) > flip furry' :: m a -> ((a -> b) -> m b) > --------------------------------------------------------------------- (T-APP) > (.) banana (flip furry') :: m a -> (m (a -> b) -> m b) > ------------------------------------------------------ (T-ARR-ASSOC') > banana . flip furry' :: m a -> m (a -> b) -> m b Basically, what's going on is that T-APP makes sure that in the expression `f x`, f :: a -> b and x :: a; and T-ARR-ASSOC and T-ARR-ASSOC' allow us to rewrite the type (a -> b -> c) as (a -> (b -> c)) and back. The interesting bit is the occurrences of T-INST. What's going on is that you're applying a polymorphic function at a more specified type. T-INST allows you to instantiate the type variables in a type so as to make stuff line up. This allows us, for example, to write: > idFunc :: (a -> b) -> (a -> b) > idFunc f = id f with the derivation: > id :: a -> a > ------------ (T-INST) > id :: (a -> b) -> (a -> b) > f :: (a -> b) > -------------------------- (T-APP) > id f :: (a -> b) In our case, we have two occurrences of T-INST. Each of them is there in order to make the type variables in (.) line up with the types of banana and furry'. The occurrences are reproduced below: > (.) :: (b -> c) -> (a -> b) -> a -> c > --------------------------------------------------------------------- (T-INST) > (.) :: ((a -> m b) -> (m a -> m b)) -> (d -> (a -> m b)) -> d -> (m a -> m b) > (.) banana :: (d -> (a -> m b)) -> d -> (m a -> m b) > --------------------------------------------------------------------- (T-INST) > (.) banana :: (m a -> ((a -> b) -> m b)) -> m a -> (m (a -> b) -> m b) Note that in order to get (.) banana to be able to get furry' as a parameter, we had to give a the type (a -> b) and d the type m a. Similarly, when we got (.) to be able to get banana as a parameter, we also forced its second parameter to be a binary function. | > |In the second solution, the types pass, i.e. the lambda is basically > furry' which has the type a -> ... -> m b, exactly what is needed in > the call to banana. But where will it get the function ab? And how > will banana work with the second argument? The definition in the class > requires it to be `m a`, but here we are passing it `m a -> m b`. | |In light of the above, you may want to recheck this claim. HTH, Gesh P.S. Sorry if this email is overly long and formal. ||| ------------------------------ Message: 3 Date: Wed, 18 May 2016 19:46:56 -0400 From: Mihai Maruseac <mihai.marus...@gmail.com> To: Haskell <hask...@haskell.org>, haskell <haskell-c...@haskell.org>, Haskell Beginners <beginners@haskell.org>, Lista principala <rosedu-gene...@lists.rosedu.org> Subject: [Haskell-beginners] ANNOUNCE: Haskell Communities and Activities Report (30th ed., May 2016) Message-ID: <CAOMsUMJAfSdeZ0qohuf-zzH606Jkp=xhf9_-my1-+jxdofv...@mail.gmail.com> Content-Type: text/plain; charset=UTF-8 On behalf of all the contributors, we are pleased to announce that the Haskell Communities and Activities Report (30th edition, May 2016) is now available, in PDF and HTML formats: http://haskell.org/communities/05-2016/report.pdf http://haskell.org/communities/05-2016/html/report.html All previous editions of HCAR can be accessed on the wiki at https://wiki.haskell.org/Haskell_Communities_and_Activities_Report Many thanks go to all the people that contributed to this report, both directly, by sending in descriptions, and indirectly, by doing all the interesting things that are reported. We hope you will find it as interesting a read as we did. If you have not encountered the Haskell Communities and Activities Reports before, you may like to know that the first of these reports was published in November 2001. Their goal is to improve the communication between the increasingly diverse groups, projects, and individuals working on, with, or inspired by Haskell. The idea behind these reports is simple: Every six months, a call goes out to all of you enjoying Haskell to contribute brief summaries of your own area of work. Many of you respond (eagerly, unprompted, and sometimes in time for the actual deadline) to the call. The editors collect all the contributions into a single report and feed that back to the community. When we try for the next update, six months from now, you might want to report on your own work, project, research area or group as well. So, please put the following into your diaries now: ======================================== End of September 2016: target deadline for contributions to the November 2016 edition of the HCAR Report ======================================== Unfortunately, many Haskellers working on interesting projects are so busy with their work that they seem to have lost the time to follow the Haskell related mailing lists and newsgroups, and have trouble even finding time to report on their work. If you are a member, user or friend of a project so burdened, please find someone willing to make time to report and ask them to "register" with the editors for a simple e-mail reminder in November (you could point us to them as well, and we can then politely ask if they want to contribute, but it might work better if you do the initial asking). Of course, they will still have to find the ten to fifteen minutes to draw up their report, but maybe we can increase our coverage of all that is going on in the community. Feel free to circulate this announcement further in order to reach people who might otherwise not see it. Enjoy! -- Mihai Maruseac (MM) "If you can't solve a problem, then there's an easier problem you can solve: find it." -- George Polya ------------------------------ Subject: Digest Footer _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners ------------------------------ End of Beginners Digest, Vol 95, Issue 24 *****************************************