Gabriella439/foldl

A question on purely_ and impurely_

sseefried opened this issue · 10 comments

Hi Gabriel,

I was wondering if you've actually used purely_? I can clearly see how to use purely but not purely_.
For instance I could write a simple function foo as follows:

foo :: (x -> a -> x) -> x -> (x -> b) -> [a] -> b
foo f z extract = extract . foldl f z

The type of this matches with the first argument of purely which is forall x. (x -> a -> x) -> x -> (x -> b) -> r. So I can then define this

foo' :: Fold a b -> [a] -> b
foo' = purely foo

However, I can't quite see how to use purely_ as it expects a first argument of type forall x. (x -> a -> x) -> x -> x

As far as I can see the only function you could write that would match this type would be

 bar f z = z 

I thought that perhaps the type of purely_ should be (forall x. (x -> a -> x) -> x -> r) -> Fold a b -> r (by looking at the type signature of purely) but then I was unable to write my own version of purely_ with that type signature.

I haven't used purely_. This was contributed on request from a user so I probably got it wrong :)

I'm fine with deleting it and incurring a breaking change

Actually I thought it was an interesting puzzle. It seems like something
like this could be useful but I couldn't actually come up with a working
example myself.

Just wanted to check if you agreed with the reasoning and whether you had
any further ideas.

On Sat, 6 Feb 2016 06:32 Gabriel Gonzalez notifications@github.com wrote:

I haven't used purely_. This was contributed on request from a user so I
probably got it wrong :)

I'm fine with deleting it and incurring a breaking change


Reply to this email directly or view it on GitHub
#57 (comment)
.

Actually, now that I think about it more closely, there is a way that you could write a function of that type. Here's a contrived example:

example :: (x -> Int -> x) -> x -> x
example step begin = step (step begin 0) 1

purely_ example :: Fold Int b -> b

Yes, I was incorrect. That's a good example. However, it and other functions you could write
like that don't seem particularly useful. I wonder if a slight change to
the type of purely_ might make it useful in the same way that purely is.

P.s. Love the foldl library. I wonder if this idea of reifying functions to
data is a truly general technique that can be used when space leaks rear
their heads. Your thoughts?

On Sat, 6 Feb 2016 10:45 Gabriel Gonzalez notifications@github.com wrote:

Actually, now that I think about it more closely, there is a way that you
could write a function of that type. Here's a contrived example:

example :: (x -> Int -> x) -> x -> x
example step begin = step (step begin 0) 1

purely_ example :: Fold Int b -> b


Reply to this email directly or view it on GitHub
#57 (comment)
.

Actually, here's another example:

\as -> Control.Foldl.purely_ (\step begin -> Data.List.foldl' step begin as)
    :: Foldable t => t a -> Control.Foldl.Fold a b -> b

More generally, purely_ was designed to provide an adapter for foldl'-like functions which often take a begin and step argument, but not a done argument

Ah, this is the example I wished I'd had! Let me write your example, slightly differently, and then
explain what my difficulties were.

folder :: Foldable t => t a -> (x -> a -> x) -> x -> x
folder as step begin = foldl step begin as

yourExample :: Foldable t => t a -> Fold a b -> b
yourExample as = F.purely_ (folder as)

I think what confused me is that when using purely_ in your example its argument is already "pre-applied" so to speak. i.e. I have applied folder to argument as to give it the required type.

I was not expecting that I had to do this as purely's type is quite a bit different, and I was hoping I could use purely_ an analogous way. I wonder if there is a way to rewrite purely_ so it looks more like purely and feels more like a "lifting" function. At the moment the type of the first argument to purely_ feels like it has been "pre-applied", if you get what I mean by that. Another way I would put it is that it seems that the "data" of the fold is implicitly "part of" the first the argument. This just seems a bit strange to, that's all.

Yeah, there's no really good way to get purely_ to work as cleanly as purely. It's hard to explain why, but if you play around with the implementation and types a bit you will see why

Yeah, I played around with it a bit to find out why before I create the
issue. It was all a bit unsatisfying. I found that I received a number of
error messages about rigid type variables escaping.

The fact that it's hard to explain is also a bit unsatisfying but, hey,
type theory is not always easy 😊

On Mon, 8 Feb 2016 15:36 Gabriel Gonzalez notifications@github.com wrote:

Yeah, there's no really good way to get purely_ to work as cleanly as
purely. It's hard to explain why, but if you play around with the
implementation and types a bit you will see why


Reply to this email directly or view it on GitHub
#57 (comment)
.

Alright, then I'll go ahead and close this for now, but thanks for taking the time to discuss this :)

No, thank you Gabriel! I've always enjoyed your blog posts, and you have been very generous with your time.