kqr 2017-01-31 19:53:51
Is "const (f . g) = f . const g" true? May be the lack of morning coffee but I'm really struggling to see it, yet there is some intuitive sense to it
kqr 2017-01-31 19:56:41
Types check out so I'll roll with it!
kqr 2017-01-31 19:57:10
Wait no they don't
kqr 2017-01-31 19:57:36
Or wait yes they do
kqr 2017-01-31 19:57:43
(you see my suffering!)
nshepperd 2017-01-31 19:58:57
:t \f g -> (const (f . g), f . const g)
lambdabot 2017-01-31 19:58:59
error:
lambdabot 2017-01-31 19:58:59
• Occurs check: cannot construct the infinite type: b1 ~ a -> b1
lambdabot 2017-01-31 19:58:59
Expected type: b2 -> b1
nshepperd 2017-01-31 19:59:43
:t \f g -> (const (f g), f . const g) -- actually this i think
kqr 2017-01-31 19:59:44
Hm
lambdabot 2017-01-31 19:59:45
(a -> c) -> a -> (b -> c, b1 -> c)
nshepperd 2017-01-31 20:02:40
(f . const g) x = f (const g x) = f g -- checks out
kqr 2017-01-31 20:12:27
yeah you're right. they don't line up quite as neatly as I'd like them to
orzo 2017-01-31 20:26:36
is a case statement matching String compiled similarly to an if-else chain? Or does the compiler do a binary search or something?
Cale 2017-01-31 20:28:10
It's compiled to a guard that uses (==)
orzo 2017-01-31 20:29:28
well, i mean beyond core
orzo 2017-01-31 20:29:48
i guess an == guard would be hard to do a binary search with
Cale 2017-01-31 20:32:48
It's sort of a weird thing to worry about because if you cared about performance, you likely wouldn't be using String. You can use string-literal pattern matches with Text, using the OverloadedStrings extension, and in that case, the fact that it compiles to a guard with (==) is reasonably good.
orzo 2017-01-31 20:33:53
it's not that i'm woried, i just like to know the run-time effects when i reorganize code
nshepperd 2017-01-31 20:33:56
it would most likely be a chain of == calls, at asm level
orzo 2017-01-31 20:34:29
changing a case to a dumb traveral over a list
nshepperd 2017-01-31 20:36:10
for data types with lots of options like data X = A | B x | C y | D, case match could be compiled into one of those fancy array dispatch thingys based on the constructor tag
orzo 2017-01-31 20:36:13
if case match is always an order-n scan, then i should feel freer to write it that way
nshepperd 2017-01-31 20:36:25
but i dunno if that ever really happens
jchia_ 2017-01-31 20:37:54
When I do the following, it's possible to get back "defabc" as well as "abcdef" when I enter "abc\ndef\n" on the console, correct?
jchia_ 2017-01-31 20:37:55
(++) <$> getLine <*> getLine
orzo 2017-01-31 20:38:12
no
orzo 2017-01-31 20:38:27
it'll always give you abcdef
jchia_ 2017-01-31 20:38:40
orzo: Why? >>= has sequencing, but <*>?
orzo 2017-01-31 20:39:20
well, you mean <*> for IO right
Cale 2017-01-31 20:39:22
af <*> ax = do f <- af; x <- ax; return (f x)
jchia_ 2017-01-31 20:39:25
orzo: yes
nshepperd 2017-01-31 20:39:30
'mf <*> mx' runs mf first, then mx, then applies the result of the first to the second
nshepperd 2017-01-31 20:39:32
in IO
jchia_ 2017-01-31 20:39:48
so the sequencing is because of how <*> is defined for IO, right?
orzo 2017-01-31 20:39:52
and probably all other side-efecting monads
orzo 2017-01-31 20:40:29
you mean, does doing different break the applicative rules?
Cale 2017-01-31 20:40:42
Yeah, generally if something is an instance of Monad, you'll have (<*>) = ap
jchia_ 2017-01-31 20:41:23
orzo: I mean generally in a Monad, >>= enforces a an order between the LHS & RHS but <*> does not, but IO defines <*> in a way that there's also an order.
jchia_ 2017-01-31 20:42:14
i mean if you define <*> with ap, you get the sequencing, but generally you don't have to.
orzo 2017-01-31 20:42:23
but <*> does and I'd be surprised if i encountered a <*> that reversed it
jchia_ 2017-01-31 20:42:24
for IO it happens to have the sequencing
orzo 2017-01-31 20:42:58
the documentation describes <*> with the word "sequence": sequence computations and combine their results (<*>).
Cale 2017-01-31 20:43:14
jchia: Well, the documentation for Applicative now states that if the functor in question is also an instance of Monad, it should satisfy (<*>) = ap
Cale 2017-01-31 20:43:39
jchia: This is mildly controversial, but a reasonably nice thing to be able to assume.
orzo 2017-01-31 20:44:36
what was the argument against
Cale 2017-01-31 20:45:12
Well, there are some very rare cases where you might want the Applicative and Monad instances to disagree.