elbear [9:08 AM]
I have a record with almost all fields having type Maybe a
. I’m setting values for fields as I’m doing some checks. is there a way to start with an empty record or to have all fields set to Nothing
without me doing that manually?
I can’t use a Map
, because values have different types
goodacre.liam [9:11 AM]
@elbear you could start with an empty record and use https://pursuit.purescript.org/packages/purescript-record/1.0.0/docs/Record#v:insert
there’s also the Record.Builder module, if that’s applicable to your usecase
elbear [9:13 AM]
@goodacre.liam do you have a more concrete example of usage than the one in the documentation. I don’t undestand how I would use insert
, just from that example
basically, I’m thinking of doing
# (\rec -> add label here)
# (\rec -> add another label)
goodacre.liam [9:15 AM]
yeah something like
{} # insert (SProxy :: SProxy "label0") (Just 42)
to give { label0: Just 42 } :: { label0 :: Maybe Int }
elbear [9:16 AM]
aha. ok, thanks!
i-am-tom [9:18 AM]
If you know the shape of the record ahead of time, mempty
will also solve the problem of “how do I get all fields to set to Nothing
unless I say otherwise”
You might need to use Last
rather than Maybe
, though, because the Monoid
instance for Maybe
is wrong (fight me @goodacre.liam)
goodacre.liam [9:20 AM]
joneshf [9:35 AM]
How is it still wrong?
I thought we learned from Haskell.
And I don’t mean, what makes it wrong.
But, why did we do the same thing as Haskell?
chexxor [9:41 AM]
What’s wrong?
elbear [9:42 AM]
maybe the Monoid
instance for Maybe
?
i-am-tom [9:43 AM]
Well well well
Haskell had instance Monoid a => Monoid (Maybe a)
and PureScript said this was nonsense, and went for instance Semigroup a => Monoid (Maybe a)
but in the McBride School of Monoids™, I put it to you that we should have instance Monoid (Maybe a)
(edited)
goodacre.liam [9:44 AM]
(^ instance Monoid (Maybe a)
)
i-am-tom [9:44 AM]
Yes, thank you
allowing us to write a law like
mempty = empty
mappend = alt
which is true for lists, parsers, etc - basically everything but Maybe
joneshf [9:45 AM]
Wait, so we didn’t follow Haskell. We’re just wrong in a different way?
i-am-tom [9:45 AM]
Depending on who’s asking, yeah
McBride’s argument is that the Maybe
type is meant to represent a computation that fails or aborts early. The current Monoid instance doesn’t fit that analogy
joneshf [9:46 AM]
K.
What does the Semigroup
instance look like?
i-am-tom [9:47 AM]
instance Semigroup (Maybe a) where append = alt
(edited)
joneshf [9:47 AM]
And what does alt
do?
i-am-tom [9:48 AM]
Just x <> _ = Just x
_ <> y = y
joneshf [9:48 AM]
Not trying to be difficult, but I thin there’s three implementations. So, looking for clarity. (edited)
K.
i-am-tom [9:49 AM]
I think he normally phrases his dismay through the Dr Seuss parser example
type Parser a = String -> List (Tuple a String)
More importantly, “A parser of things is a function of strings to lists of pairs of things and strings”
"I get alt for free with lists, but not with Maybe
joneshf [9:49 AM]
Is this the current instance for First _
?
i-am-tom [9:49 AM]
yeah
joneshf [9:49 AM]
K.
i-am-tom [9:49 AM]
though that should strictly be a semigroup
joneshf [9:49 AM]
And why don’t we want to do this?
i-am-tom [9:49 AM]
(and not a monoid)
history, I guess? It’s a departure from Haskell that is bound to upset people
joneshf [9:50 AM]
Does the Semigroup
and Functor
hierarchy have to interact in this way?
i-am-tom [9:50 AM]
I mean, none of them have to interact in any way, but we like laws
I suppose the answer is “apparently not” given that Conor never got his way
joneshf [9:51 AM]
What I’m getting at is that if this makes things more consistent, and we value consistency, we should make this change.
i-am-tom [9:52 AM]
cue @goodacre.liam
goodacre.liam [9:52 AM]
in some situations when we have two classes that we want to interact, we make a new sub class and attach the laws there
joneshf [9:53 AM]
Like Applicative
, Bind
, and Monad
? (edited)
i-am-tom [9:53 AM]
More like BoundedEnum
, I guess
class (Bounded a, Enum a) => BoundedEnum a
actually no, I’m probably talking rubbish - I think that one comes with functions too
goodacre.liam [9:53 AM]
class (EuclideanRing a, DivisionRing a) <= Field a
(edited)
joneshf [9:54 AM]
Are you suggesting with create a new class instead of altering the current instances?
goodacre.liam [9:54 AM]
Not suggesting anything, just that it could be an option
joneshf [9:55 AM]
K.
goodacre.liam [9:55 AM]
class (Alt a, Semigroup b) <= AltSemigroup (a b)
but yeah, my original argument when I first talked about this with Tom was that I can recover the First
style instance by picking a different monoid, but not the other way around;
and that it wasn’t clear that the instances were supposed to interact as suggested,
there’s also the argument of not picking an instance when there are multiple sensible ones, etc
I’m not particularly tied to the current interpretation
:troll: what if Alt
should have been
alt :: Semigroup a => f a -> f a -> f a
sellout [10:15 AM]
What if Alt
should have been Monoid
?
joneshf [10:17 AM]
Polykinds?
and that it wasn’t clear that the instances were supposed to interact as suggested,
I think I’m in this camp.
If it supposed to be this way, I’m all for it. But I don’t know if it is.
sellout [10:20 AM]
@joneshf you don’t need polykinds to eliminate Alt. It’s just a Monoid instance.
goodacre.liam [10:20 AM]
quantified constraints?
(forall a . Monoid (Maybe a))
(edited)
sellout [10:21 AM]
I think … I sometimes mix up the different Alt-like names in different languages. But they mostly represent monoids in Set.
sellout [10:29 AM]
Any Alt instance on f can be rewritten as instance Monoid (f a)
no?
Denis Stoyanov [10:32 AM]
I think maybe it will be like nearsemiring? (monadplus is nearsemiring in category of endofunctors)
i-am-tom [11:43 AM]
@sellout Yeah exactly, we can think of an Alt
as “a semigroup that doesn’t care about the inner value”, I guess (edited)
m’colleague @blouerat beautifully terms it, “the universally-quantified semigroup” :