Search Haskell Channel Logs

Sunday, February 26, 2017

#haskell channel featuring jle`, Cale, notjack-rkt, tempeh, lambdabot, dolio,

notjack-rkt 2017-02-26 16:57:57
Sure but racket lenses aren't exposed as functions in the van Laarhoven encoding, you just pass the lens to a `lens-view` function or a `lens-set` function.
notjack-rkt 2017-02-26 16:58:14
So the typeclassery and van Laarhoven encodings aren't super relevant to racket-land.
Cale 2017-02-26 16:59:03
It's harder to say what the abstract interface to Traversals would look like, in the sense that you have view and set for lenses.
notjack-rkt 2017-02-26 17:01:48
right that's something I'd like to figure out with this conversation
notjack-rkt 2017-02-26 17:03:33
Cale: right that I understand
Cale 2017-02-26 17:04:45
and
Cale 2017-02-26 17:06:07
:t \f v -> pure v
lambdabot 2017-02-26 17:06:07
Applicative f => t -> a -> f a
Cale 2017-02-26 17:06:07
which is an empty traversal
Cale 2017-02-26 17:06:07
So I suppose if we had a class for pointed functors (i.e. functors f which had an operation a -> f a), we'd end up with something a little closer to traversals over 0 or 1 things in that way
notjack-rkt 2017-02-26 17:06:08
view seems easy enough to generalize into the abstract interface of traversal, but I'm not sure what `set` would look like - set each viewed item of the traversal all to the same value?
Cale 2017-02-26 17:07:14
Well, to set, we use the identity functor
notjack-rkt 2017-02-26 17:07:31
with the point in the pointed functor being used for the zero-items case?
Cale 2017-02-26 17:07:34
and if we're ignoring the values which were already there, we provide a constant function
dolio 2017-02-26 17:08:00
You don't view and set one thing with a traversal.
Cale 2017-02-26 17:08:09
@let myBoth f (x,y) = liftA2 (,) (f x) (f y)
lambdabot 2017-02-26 17:08:12
Defined.
dolio 2017-02-26 17:08:17
You view n things and set n of them, where n is determined by the exact structure of the thing you're viewing/setting.
notjack-rkt 2017-02-26 17:09:00
dolio: which can't be changed I presume? as in setting n-1 or n+1 things would break
Cale 2017-02-26 17:09:17
> set myBoth 5 (1,2)
lambdabot 2017-02-26 17:09:21
(5,5)
dolio 2017-02-26 17:09:22
Right. You have to set as many things as you view.
notjack-rkt 2017-02-26 17:09:47
dolio: How would that be different from a lens that views a list?
dolio 2017-02-26 17:09:48
Luckily in your case you don't have to worry about infinities. :)
Cale 2017-02-26 17:09:53
> myBoth (const (Identity 5)) (1,2)
lambdabot 2017-02-26 17:09:56
Identity (5,5)
Cale 2017-02-26 17:10:01
> runIdentity (myBoth (const (Identity 5)) (1,2))
lambdabot 2017-02-26 17:10:05
(5,5)
dolio 2017-02-26 17:10:23
A lens that views a list could change the size of the list, presumably.
Cale 2017-02-26 17:10:35
> myBoth (\x -> Identity (10*x)) (1,2)
jle` 2017-02-26 17:10:37
it's also...a different type
lambdabot 2017-02-26 17:10:37
Identity (10,20)
Cale 2017-02-26 17:10:51
^^ so you can map over the targets of a traversal in that way
erisco 2017-02-26 17:10:56
that never stopped a dynamic programmer
Cale 2017-02-26 17:11:05
(and that's what ultimately lets you set them)
dolio 2017-02-26 17:11:46
Lens is: s -> (a, a -> s) ; traversal is: s -> ∃n. (Vector n a, Vector n a -> s)
notjack-rkt 2017-02-26 17:12:16
dolio: In racket land there's no types so you'd enforce the size of the list dynamically
dolio 2017-02-26 17:12:16
For a type of statically sized vectors.
dolio 2017-02-26 17:12:57
Well, in that case, I suppose there's not much difference.
Cale 2017-02-26 17:13:01
notjack-rkt: Now what you could do is just give someone pure and (<*>) as arguments, and say "hey, do whatever"
Cale 2017-02-26 17:13:06
i.e. dictionary passing
Cale 2017-02-26 17:13:37
That might be preferable to having to produce a vector of them and be careful about the sizes
notjack-rkt 2017-02-26 17:14:13
Cale: I want something that spiritually matches the lens interface, which is basically just "construct a lens from this getter and this setter"
dolio 2017-02-26 17:14:39
notjack-rkt: There's also a funky nested type you can use. If you used something like that in Racket it might be closer. I'd have to think about what it is, though.
tempeh 2017-02-26 17:15:40
anyone happen to know the behavior of nix options in stack.yaml on machines without nix installed? just ignored, or error?
notjack-rkt 2017-02-26 17:16:23
If you throw the types out the window, what, conceptually, is the difference between a lens that views a maybe and a traversal that views zero or one elements?
notjack-rkt 2017-02-26 17:16:31
What can I do with one that I can't without the other?
Cale 2017-02-26 17:17:03
dolio, notjack-rkt: Right, either you're done and there are no more targets to replace, or you have another target, and you have a way to replace it which will give you another partially-completed traversal
notjack-rkt 2017-02-26 17:18:08
Cale: do you mean there isn't a difference in functionality between those two things?
dolio 2017-02-26 17:18:17
A lens that views a maybe can change a nothing to a just or vice versa. A traversal can't.
notjack-rkt 2017-02-26 17:18:27
ahhh, now I see
notjack-rkt 2017-02-26 17:18:47
So a traversal doesn't allow changing the number of elements while a lens viewing multiple things would
Cale 2017-02-26 17:18:51
wait
Cale 2017-02-26 17:19:01
Every lens is also a traversal
dolio 2017-02-26 17:19:11
notjack-rkt: Like, when I said that there 'wouldn't be a difference,' it'd be because you're blowing up if I give you the wrong number of elements.
Cale 2017-02-26 17:19:40
But you mean the traversal which actually digs in and gets you the argument to the Just, which wouldn't be a lens
notjack-rkt 2017-02-26 17:19:55
Cale: Yes
notjack-rkt 2017-02-26 17:20:10
I don't mean the traversal you get from a lens, I mean a traversal that is *necessarily* a lens because it digs into a maybe
Cale 2017-02-26 17:20:30
That necessarily fails to be a lens?
notjack-rkt 2017-02-26 17:21:12
Yes but I'm trying to work out how I'd use it in the nested-thing-in-hash-in-thing problem
Cale 2017-02-26 17:21:17
Here: data PartialTraversal s a = Done s | More s (a -> PartialTraversal s a)
Cale 2017-02-26 17:21:33
So then a traversal will be a function s -> PartialTraversal s a
Cale 2017-02-26 17:21:55
oops
Cale 2017-02-26 17:21:55
Here: data PartialTraversal s a = Done s | More a (a -> PartialTraversal s a)
Cale 2017-02-26 17:21:59
(typo)
Cale 2017-02-26 17:22:44
So when you hit something of type s with this traversal, you're either going to get Done with some value of type s (there were no targets to traverse over)
Cale 2017-02-26 17:23:21
or you're going to get the first target, together with a function which will take the replacement and give you another partial traversal
notjack-rkt 2017-02-26 17:24:11
and in order to be total, you must assume you don't know how many targets you'll get
Cale 2017-02-26 17:24:17
yeah
notjack-rkt 2017-02-26 17:24:34
which is why you can set everything or map everything but not set a fixed N values
Cale 2017-02-26 17:25:11
Yeah -- well, you can be a bit "stateful" as you go
notjack-rkt 2017-02-26 17:25:26
right, but I can't assume count without becoming partial
dolio 2017-02-26 17:25:38
I'm not sure that type gives you all the power you'd have in a real traversal.
Cale 2017-02-26 17:25:48
It doesn't handle the type changing thing
dolio 2017-02-26 17:26:04
No, I mean, you have to feed in a value to see the rest of the traversal.
Cale 2017-02-26 17:26:11
hmm, that's fair
dolio 2017-02-26 17:26:17
It's really complicated to look ahead, at best.
Cale 2017-02-26 17:26:20
But wait
Cale 2017-02-26 17:26:28
Do you actually get to see that with a real traversal?
notjack-rkt 2017-02-26 17:26:51
keep in mind I don't need to handle type changing since, y'know, no types
dolio 2017-02-26 17:27:02
Yes, at least a finite one, I think.
Cale 2017-02-26 17:27:21
notjack-rkt: that's fair, but it still can matter ;)
Cale 2017-02-26 17:27:21
notjack-rkt: Your compiler doesn't have to care about types, but you do ;)
notjack-rkt 2017-02-26 17:27:51
Yes but I don't need to explain my reasoning to a `data` declaration :)
Cale 2017-02-26 17:28:12
dolio: I mean, you're going to see each of the targets via the function (a -> f b) you supply, and each one is obtained sort of in isolation, no?
Cale 2017-02-26 17:29:24
Only the Applicative machinery and the traversal itself gets to know the big picture
Cale 2017-02-26 17:30:15
We can of course count the number of targets or construct a list of them
dolio 2017-02-26 17:30:16
Cale: I think, consider that: /\b -> ∃n. a^n * (a^n -> b) is applicative.
notjack-rkt 2017-02-26 17:30:25
Right
dolio 2017-02-26 17:30:34
Where pure uses n = 0, and pair adds the ns.
dolio 2017-02-26 17:30:58
Dividing them between the two pieces.
dolio 2017-02-26 17:31:58
Then if you traverse with that applicative, you get a thing that lets you see all the as at once.
Cale 2017-02-26 17:32:40
hmmm
Cale 2017-02-26 17:33:17
Whereas the Applicative you need to use in my case is probably some horrifying Cont monstrosity ;)
dolio 2017-02-26 17:34:11
That type might not be exactly correct, but probably something along those lines works.
Cale 2017-02-26 17:35:34
(You could probably use recursion to determine the values to replace stuff with later, with some tying-the-knot style trickery)
dolio 2017-02-26 17:35:53
Yeah, maybe. I don't know if that works in Racket, though.
Cale 2017-02-26 17:35:53
But yeah
Cale 2017-02-26 17:36:03
Yeah, I don't know either :)
Cale 2017-02-26 17:37:37
oh, but what we *could* do is what you were perhaps hinting at earlier, and use type-changing recursion (which will probably be much harder to get right as a programmer in racket, but whatever)
Cale 2017-02-26 17:38:06
data PartialTraversal s a = Done s | More a (PartialTraversal (a -> s) a)
Cale 2017-02-26 17:38:36
Now you get the targets one at a time, and at the end, you get a function which takes all the replacements
dolio 2017-02-26 17:38:44
Yeah.
dolio 2017-02-26 17:38:54
That's probably the type I was thinking of.