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) 1purely_ 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.