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: function application (Silent Leaf) 2. Re: Haskell triangular loop (correct use of (++)) (Jon Surrell) ---------------------------------------------------------------------- Message: 1 Date: Tue, 12 Apr 2016 01:52:46 +0200 From: Silent Leaf <silent.le...@gmail.com> To: mike h <mike_k_hough...@yahoo.co.uk>, The Haskell-Beginners Mailing List - Discussion of primarily beginner-level topics related to Haskell <beginners@haskell.org> Subject: Re: [Haskell-beginners] function application Message-ID: <cagfccjo9bxfugra0jbxfgmrgwxvm4++iafisxzbaecdjghx...@mail.gmail.com> Content-Type: text/plain; charset="utf-8" true! no it's totally my fault, i forgot about that. I'm not exactly sure why is that, it seems slightly absurd, limiting, to me but I guess it must be something on the inside. In that case, from what I know to this day, you'll have to choose either, and I know no easy way to integrate a point-free conditional choice (in other terms, to replace the guards in a pointfree manner) on one of the parameters, so I'd go for the non-pointfree style, aka your original implementation, with the guards. of course we can merrily cheat: test1arg :: (a -> b) -> (a -> b) -> (a -> Bool) -> a -> b test1arg cond thenF elseF x | cond x = thenF x | otherwise = elseF x then: mc :: Integral a => a -> a mc = test1arg (<100) (-10) (mc . mc . (+11)) it amounts to moving the guards into another function. the "if then else" expression is very similar of course, but doesn't allow, as far as I know, point-free style. Anyway... all this becomes a pointless (pun unintended) search for the point-free style at all costs. I'm not sure it's generally speaking, a very good idea. Non-point-free style is perfectly good style in itself, and pointfree should be in my opinion reserved to cases where it comes naturally, where, when perhaps looking at one's definition for a function, one realizes the presence of the argument is pointless; one very random last-minute example: f xs = zip [0..] xs ---> f = zip [0..] also to the cases when the very definition of a function comes to one as combination of other functions. beyond that, I'd say it's mostly wasted time. I think the question is to balance the style, to always prefer clarity to "coolness" at any rate. Sure, in many cases, a pointfree style is in my opinion much quicker to understand, much clearer. Also, pointfree style is also a very good exercise I think, that permits beginners (i put myself in it needless to say) to get a better understanding of haskell's syntax, and of the whole function paradigm in general. As long as exercises in pointfree feats aren't hindering real programming, I'd say there's no problem in trying to go for it whenever it's possible. Plus in my opinion it can be fun. 2016-04-11 16:16 GMT+02:00 mike h <mike_k_hough...@yahoo.co.uk>: > Hi, > > Thanks for the comprehensive and considered answers. > Maybe I'm missing something but defining the original function to have two > definitions with a different number of args in each causes a compiler > error ie. doing > > mc :: (Integral a) => a -> amc x | x < 100 = x - 10 -- 1 arg > mc = mc . mc . (+ 11) -- no args > > Thanks > > > > > On Sunday, 10 April 2016, 22:29, Silent Leaf <silent.le...@gmail.com> > wrote: > > > Mike: If you seek as I think you do, to write the function mc (partially) > in point-free style, you must know this style implies no arguments, or at > least not all arguments, mentioned, that is for example here: > mc x | x < 100 = x - 10 > mc = mc . mc . (+ 11) > > The second line will only be checked for pattern matching if the first one > fails, so it amounts to the "otherwise" guard as here there's no pattern, > so it's a bit like the pattern that always matches (mc _ = ...) > You'll remark I did write (mc =) and not (mc x =). Point free style > amounts to describing a function through a composition of other functions, > in an arguments-free way, here for example, (mc . mc . (+11)) being the > composition of mc twice, with the "partially-applied" function (+11) == (\x > -> x + 11) == (11+). This partially applied notation works for all > operators by the way. > > And for the record, the whitespace operator is a pure myth. First you can > remove all whitespace, it still works. Second, try using the same > whitespace-induced universal right-associativity with (f a b): does it > amount to (f (a b))? > > The reason for this right-associativity interpretation in (mc . mc (x + > 11)) is because (.) itself is right associative: right-directed greediness > could we say, in the vocabulary of regular expression. It's also the case > of ($), and that's why we use it to counter the natural left associativity > of function application: > f $ g a == f $ (g a) == ($) f (g a) == f (g a) -- (using the definition > of ($) here) > instead of > f g a == (f g) a > without using ($). > > The whitespace is just a meaningless character (I guess, a set of > characters) used to separate juxtaposed meaningful tokens of the language > when we have either (symbol,symbol) or (nonsymbol,nonsymbol), for example > respectively (!! $ /= !!$) and (f g /= fg). whenever it's a nonsymbol and a > symbol, whitespace is not necessary (a+, +a). > Then there's the automatic, implicit function application between two > juxtaposed non-symbolic tokens. But the whitespace has never been an > operator of any kind, and is totally meaningless (and optional) in (mc . mc > (x + 11)). > > Especially too, it's clear no whitespace survives the tokenization during > the lexical phase of the (pre?) compilation, contrarily to all real > operators like (+). > > > _______________________________________________ > Beginners mailing list > Beginners@haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > > > > _______________________________________________ > Beginners mailing list > Beginners@haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.haskell.org/pipermail/beginners/attachments/20160412/4b52c3f3/attachment-0001.html> ------------------------------ Message: 2 Date: Tue, 12 Apr 2016 07:57:41 +0000 From: Jon Surrell <jon.surr...@gmail.com> To: The Haskell-Beginners Mailing List - Discussion of primarily beginner-level topics related to Haskell <beginners@haskell.org> Subject: Re: [Haskell-beginners] Haskell triangular loop (correct use of (++)) Message-ID: <CAPdG00VwzMhNR+XRw_TTfMgko-JUR2aT1YwF0ZjF_hpxk0=e...@mail.gmail.com> Content-Type: text/plain; charset="utf-8" Rein's comment about taking advantage of laziness and sharing over memoization made an impact with me. Seeing it stated like that, it seems obvious. Does anyone know of resources that explain this type of restructuring, preferably with practical examples? Thanks, Jon On Mon, Apr 11, 2016 at 11:12 PM Rein Henrichs <rein.henri...@gmail.com> wrote: > I should also mention that many times when you think you want memoization > in Haskell, what you actually want is to restructure your computation to > take better advantage of laziness (and especially sharing). > > On Mon, Apr 11, 2016 at 2:10 PM Rein Henrichs <rein.henri...@gmail.com> > wrote: > >> Compilers generally don't provide memoization optimizations because there >> isn't a single dominating strategy: it varies on a case-by-case basis. (For >> example, memoization of some functions can take advantage of structures >> with sub-linear indexing, but this can't be done generically.) >> >> When you can implement your own memoization yourself within the language >> with exactly the properties you desire (and a number of libraries have >> already done so for many common strategies ([1], [2], [3], [4])), there has >> been little motivation to add an implementation to GHC which is either >> inferior by way of its generality or extremely complex by way of its many >> special cases. >> >> [1]: https://hackage.haskell.org/package/MemoTrie >> [2]: https://hackage.haskell.org/package/memoize >> [3]: http://hackage.haskell.org/package/data-memocombinators >> [4]: https://hackage.haskell.org/package/representable-tries >> >> On Sun, Apr 10, 2016 at 10:06 PM Silent Leaf <silent.le...@gmail.com> >> wrote: >> >>> I'm sorry to hear, no implicit memoization (but then is there an >>> explicit approach?). in a pure language, this seems hardly logical, >>> considering the functional "to one output always the same result" and the >>> language's propensity to use recursion that uses then previous values >>> already calculated. Really hope for an explicit memoization! and i don't >>> mean a manual one ^^ if that is even possible? >>> >>> Anyway, i just don't get your function f. you did get that in mine, xs >>> was the value of my comprehension list, aka [.s1..n] ++ [0] >>> From there, if I'm not wrong, your function creates a list of all >>> truncated lists, I supposed to be used with a call for the nth element? >>> True, it memorizes all needed things, and in theory only "drops" once per >>> element of the list. >>> >>> As for incorporating it, i'm thinking, local variable? ^^ the function >>> itself could be outside the comprehension list, in a let or where, or >>> completely out of everything, I don't really see the problem. then it's >>> just a matter of it being called onto xs inside the comprehension list, >>> like that: >>> result = [(x,y) | let xs = [1,2,3,0], let yss = f xs, (x,i) <- zip xs >>> [1,2..], y <- yss !! i, x /= y] >>> The remaining possible issue is the call to !!... dunno if that's costy >>> or not. >>> >>> The best way to go through the list I suppose would be by recursion... >>> oh wait, I'm writing as I'm thinking, and I'm thinking: >>> result = [(x,y) | let xs = [1,2,3,0], let yss = f xs, x <- xs, ys <- >>> yss, y <- ys, x /= y] >>> after all, why not use the invisible internal recursion? What do you >>> think? >>> >>> As for the number-instead-of-number-list, the crucial point i mentioned >>> was to determine the maximum number of digit (biggest power of ten >>> reached), and fill up the holes of the smaller numbers with zeroes, so your >>> examples would be: >>> [1,2,3] = 123 --maximum size of a number = 1, no need to fill up >>> [12,3] = 1203 --maximum size of a number = 2 digits, thus the hole >>> beside 3 gets filled with a zero, just like on good old digital watches ^^ >>> Do you think extraction of clusters of digits from numbers would be >>> advantageous, efficiently speaking? >>> _______________________________________________ >>> Beginners mailing list >>> Beginners@haskell.org >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners >>> >> _______________________________________________ > Beginners mailing list > Beginners@haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.haskell.org/pipermail/beginners/attachments/20160412/cd47533e/attachment.html> ------------------------------ Subject: Digest Footer _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners ------------------------------ End of Beginners Digest, Vol 94, Issue 9 ****************************************