Search Haskell Channel Logs

Saturday, January 28, 2017

#haskell channel featuring dgpratt, reactormonk, ertes, ph88,

ph88 2017-01-28 03:45:18
anyway i'll save it as note, maybe it will be useful later on
ertes 2017-01-28 03:45:24
ph88: lbl = sequenceA (BS_Index (n get) (o $ …))
ph88 2017-01-28 03:46:52
you want to put everything on one line ?
ertes 2017-01-28 03:47:22
ph88: no, not necessarily, but you can keep the actions to generate a certain field *within* that field… it makes the code clearer (IMO)
ertes 2017-01-28 03:47:30
and shorter, too, because you can avoid stuff like 'rest'
ertes 2017-01-28 03:48:15
ah, wait
ertes 2017-01-28 03:48:31
it wouldn't work as easily in your case =/
ph88 2017-01-28 03:49:06
aaah ok, so where i normally do BS_Index a b c i can now do sequenceA $ BS_Index (m a) (m b) (m c) ??
ertes 2017-01-28 03:49:27
ph88: that's the idea, but it wouldn't work
ph88 2017-01-28 03:49:31
o_O
ertes 2017-01-28 03:50:29
ph88: for Traversable to work you need to abstract over a certain type, and i see no obvious good choice =/
ph88 2017-01-28 03:50:32
before when i want to put everything on one line and save some verbosity of the do-notation i would just use applicative style BS_Index <$> (m a) <*> (m b) <*> (m c)
ertes 2017-01-28 03:51:05
ph88: you don't need to put everything on one line… i usually line up the (<$>) and (<*>) on separate lines
ph88 2017-01-28 03:51:11
ertes, what's the problem with the current types that they are not an obvious good choice ?
ertes 2017-01-28 03:51:41
BS_Index\n<$> action1\n<*>action2
ertes 2017-01-28 03:52:25
data BlockSpecification a = BS_Name a | BS_Index a a -- not a good choice, because the types differ
ertes 2017-01-28 03:52:58
data BlockSpecification = BS_Name (NT Name) | BS_Index (NT Label) (Maybe (a, (NT IndexSpecification), a)) -- probably not a good choice either, because of the way you construct these
ertes 2017-01-28 03:53:06
+ a
ph88 2017-01-28 03:54:14
alright thanks, at least i learned about sequenceA :)
ph88 2017-01-28 03:54:33
so it replaced a bunch of <*> right ?
ertes 2017-01-28 03:58:42
ph88: it's basically a replacement for applicative style that is structure-aware
ertes 2017-01-28 03:59:36
sequenceA (C action1 action2 (Just action3) (action4, action5)) -- this is awkward at best to code with applicative style
ertes 2017-01-28 04:00:09
C <$> action1 <*> action2 <*> (Just <$> action3) <*> (liftA2 (,) action4 action5) -- ugly
ph88 2017-01-28 04:00:27
ah ok, that's how i would write it, ugly :P
ertes 2017-01-28 04:01:01
it gets worse when you have named fields, while with traverse/sequenceA you can just write: sequenceA (C { field1 = action1, field2 = action2 })
ertes 2017-01-28 04:01:47
compare: (\x y -> C { field1 = x, field2 = y }) <$> action1 <*> action2 -- not only is this a lot harder to read, but the actions are syntactically disconnected from the fields they correspond to
ph88 2017-01-28 04:02:02
yes i noticed this already with records :/
ph88 2017-01-28 04:02:12
ok good tip, i'll see where i can apply it in parts of my code
reactormonk 2017-01-28 04:02:29
Can I have a local typeclass instance, by not exporting it?
ertes 2017-01-28 04:02:35
(-XApplicativeDo makes this particular case a lot better, but still needs you to come up with temporary names, so sequenceA is still nicer)
dgpratt 2017-01-28 04:02:44
I just stumbled across https://github.com/sdiehl/protolude which I thought looked pretty nice; anyone here have feelings about it, positive or negative?
ertes 2017-01-28 04:02:59
reactormonk: you can't not export instances
ph88 2017-01-28 04:03:15
ertes, what's the difference here between traverse and sequenceA then? i see the type signatures .. but when would you use which one ?
ertes 2017-01-28 04:03:16
reactormonk: type classes follow an open world principle
ph88 2017-01-28 04:03:34
looking at it's type signature sequenceA doens't even do anything
ph88 2017-01-28 04:03:41
oh wait it does
ph88 2017-01-28 04:03:44
swap t and f
ertes 2017-01-28 04:03:52
ph88: very often you have this: sequenceA (C (f x1) (f x2) (Just (f x3)) (f x4, f x5))
ertes 2017-01-28 04:04:16
ph88: you can write: traverse f (C x1 x2 (Just x3) (x4, x5))
ph88 2017-01-28 04:04:18
ah ok and then when you want to do the same but with map it becomes traverse ?
ph88 2017-01-28 04:04:23
yes ok
ph88 2017-01-28 04:04:27
thanks
reactormonk 2017-01-28 04:04:49
ertes, what are the implications?
ertes 2017-01-28 04:04:50
ph88: if you have a Functor: traverse f = sequenceA . fmap f
ertes 2017-01-28 04:04:59
reactormonk: that you can't not export instances =)
reactormonk 2017-01-28 04:05:06
ertes, oke
ertes 2017-01-28 04:05:20
reactormonk: also you can't not import them, except by not importing the module (not even transitively)
ertes 2017-01-28 04:05:42
reactormonk: you should assume that as soon as you define an instance, that instance is world-wide
ertes 2017-01-28 04:06:20
reactormonk: (that's why orphan instances should be avoided)