Closed mikesol closed 3 years ago
At a glance I'm not sure what the issue is. Pinging @MonoidMusician and @LiamGoodacre if they have any extra insight here. Regardless -- definitely a bug, thank you for reporting it!
Is it this line that is blowing up? https://github.com/purescript/purescript-profunctor/blob/9b3d014b38c69ea2dd4b1f597330b095034fe2c4/src/Data/Profunctor/Costar.purs#L62
It's a questionable instance because it relies on laziness to work – it doesn't work out mathematically. In particular, bd
is defined by passing a value to f
that depends on snd bd
!
I'm trying to think if there's any possible instances where it works … it might be that PureScript is too strict. (Ideally the call to snd bd
would be guarded under another lambda.) I guess it depends on how the Functor f
instance works. If it's something lazy like (co)yoneda, and the function f
does not inspect its argument at all, it could work. But that's almost never the case.
Anyways, it also doesn't work out for your example either. For Costrong you want a function (Tuple a c -> r) -> a -> r
(desugared), but you cannot magically come up with a value of the arbitrary c
type to pass to the f
function. More particularly, (Tuple Unit Void -> Void) -> Unit -> Void
is uninhabited in a consistent type theory.
Yup, that's the line. I talked about it a bit on the purescript Slack as well. One course of action suggested by @LiamGoodacre is to delete the Costrong implementation in Costar. Conceptually, Costrong only makes sense if you have a type that is guaranteed to ignore mapping (ie Const
) in a strict language, and in a lazy language, I'm assuming this translates to "guaranteed to never touch c
in Tuple a c
", which seems like a really severe constraint. Otherwise, I don't see how you could magically uncook the pizza and go from Tuple a c -> Tuple b c
to a -> b
.
@LiamGoodacre I'm curious about fixing this for the upcoming breaking release of this library. Do you have a suggested course of action we could take in a PR?
It's not clear to me that there's a fix. Seems like something that can't/shouldn't exist.
My suggestion is to delete the rogue instance.
Seems unlikely that any code depends on it - any that does is likely also broken or unused.
(Cochoice (Costar f)
may also be suspect?).
Thanks, Liam. @mikesol, is there any chance you'd be interested in taking on a PR to remove that instance?
I agree that Cochoice (Costar f)
is also dodgy and should be removed if we are removing Costrong (Costar f)
.
I've been digging into this (great!) repo and trying to create accumulating getters, meaning getters that can "pause" at a certain point of the lens, take a value, and persist it down to the final getter.
Rolling one by hand is pretty easy for a specific scenario, but coming up with a generic way to do this seems impossible. Nonetheless, the signature of
Costar
makes it seem like it's possible, asCostar
can theoretically be used to "upgrade" a vanilla optic to an optic that takes a tuple (as I do below). However, it crashes with an odd message. The only crash I've ever seen in purescript before is maximum recursion depth (aka bottom), but this seems like a different beast...I can also write this up in the
purescript-profunctor
library if the issue lies more there than here. Curious to hear everyone's thoughts.Environment
purescript-profunctor-lenses
6.3.0Current behavior
This compiles fine but crashes when run:
Yields:
Expected behavior
Not quite sure... definitely not a crash, but it's still unclear what the expected would be.