WEBVTT

1
00:00:04.840 --> 00:00:07.630
>> Hello.

2
00:00:07.640 --> 00:00:10.310
Welcome to the Haskell Weekly Podcast. I'm your host,

3
00:00:10.320 --> 00:00:12.280
Cameron Gera. An engineer at

4
00:00:12.290 --> 00:00:14.940
ITProTV. And with me today is

5
00:00:14.950 --> 00:00:17.710
Taylor Fausak one of my boss?

6
00:00:17.710 --> 00:00:20.200
Actually, he's not. He's on my team, but he's my boss as well,

7
00:00:20.210 --> 00:00:23.190
but we're just super excited to be here today. How you doing

8
00:00:23.190 --> 00:00:23.560
today?

9
00:00:24.340 --> 00:00:27.260
>> I'm doing well, Cam. Thanks for hosting me on the show this

10
00:00:27.260 --> 00:00:27.650
week.

11
00:00:27.660 --> 00:00:30.500
>> Of course, man. We're on episode 35. That's

12
00:00:30.500 --> 00:00:33.290
a big deal. So thank you all for listening. And

13
00:00:33.290 --> 00:00:36.160
we're hoping you'd like to stick around.

14
00:00:36.740 --> 00:00:38.570
So Taylor what are we talking about today?

15
00:00:39.540 --> 00:00:42.210
>> So today we're gonna be digging into a post

16
00:00:42.210 --> 00:00:44.870
about kind of, maybe versus

17
00:00:44.870 --> 00:00:47.800
either and error reporting. But

18
00:00:47.800 --> 00:00:49.880
before we get to that, I think we have

19
00:00:49.890 --> 00:00:52.710
announcement from the community at

20
00:00:52.710 --> 00:00:55.440
large, not an announcement from us that we should talk about a little

21
00:00:55.440 --> 00:00:58.250
bit, which is the GHC

22
00:00:58.260 --> 00:01:01.110
2021 proposal has been accepted.

23
00:01:01.120 --> 00:01:03.670
So, uh, yeah, very

24
00:01:03.670 --> 00:01:06.350
exciting. Cam, I know we talked about this on a previous

25
00:01:06.350 --> 00:01:09.320
episode of the podcast, but you got anything to say about it now that

26
00:01:09.320 --> 00:01:10.270
it's accepted?

27
00:01:10.840 --> 00:01:13.810
>> I mean, I think I think it's cool I think it's interesting to see

28
00:01:13.810 --> 00:01:16.790
the data and how the votes went. As far as the committee.

29
00:01:16.800 --> 00:01:19.440
Selecting what? To bring in what? Not to bring in.

30
00:01:19.450 --> 00:01:22.360
Um, still for me. Personally shocked. Overloaded strings

31
00:01:22.360 --> 00:01:24.880
isn't there? But that's okay. You know, we can

32
00:01:24.890 --> 00:01:27.850
continue to enable that extension for

33
00:01:27.850 --> 00:01:29.960
us. It helps with our, uh,

34
00:01:30.440 --> 00:01:31.460
API Development.

35
00:01:32.040 --> 00:01:34.830
>> Yeah, I think it's one of the most popular extensions. But

36
00:01:34.830 --> 00:01:37.660
this since it's the first cut of this new process, I

37
00:01:37.660 --> 00:01:40.330
think they tried to play it a little safe. And overloaded

38
00:01:40.330 --> 00:01:43.230
strings can introduce a lot of ambiguity. So I see why.

39
00:01:43.230 --> 00:01:44.450
Maybe they left it off.

40
00:01:44.460 --> 00:01:47.460
>> That's fair. That's fair. Yeah. I mean, you know,

41
00:01:47.460 --> 00:01:50.010
they did great work with keeping it backwards

42
00:01:50.010 --> 00:01:52.550
compatible with Haskell 2010 and all that stuff.

43
00:01:52.840 --> 00:01:55.560
Um, but yeah. Do you have any,

44
00:01:55.560 --> 00:01:58.410
like, uh, just give ah, listener quick

45
00:01:58.420 --> 00:02:01.120
point of like, what's the difference between this and, you know,

46
00:02:01.130 --> 00:02:02.860
a language standard?

47
00:02:03.540 --> 00:02:06.530
>> Sure. Once again, I'll point back to our previous

48
00:02:06.530 --> 00:02:09.400
episode in October, where we talked about this in a little more detail.

49
00:02:09.410 --> 00:02:12.360
But, um, this isn't a full blown new

50
00:02:12.360 --> 00:02:15.180
version of the Haskell language report, so It's

51
00:02:15.180 --> 00:02:17.860
not like a new standard. And the difference

52
00:02:17.870 --> 00:02:20.720
is that are, like the pragmatic differences that

53
00:02:20.720 --> 00:02:23.670
GHC 2021 is a language extension

54
00:02:24.040 --> 00:02:26.700
that just enables a bunch of other language

55
00:02:26.700 --> 00:02:29.560
extensions. So it's like an alias for these other

56
00:02:29.560 --> 00:02:31.990
things. Um, and a new version of the

57
00:02:31.990 --> 00:02:34.640
standard would be hopefully

58
00:02:34.640 --> 00:02:37.530
well specified enough that someone

59
00:02:37.530 --> 00:02:40.380
will be able to implement a different compiler that

60
00:02:40.390 --> 00:02:43.160
implements that standard. So most of the time,

61
00:02:43.160 --> 00:02:45.950
GHC is the only compiler that we talk about. But

62
00:02:45.960 --> 00:02:48.420
there are others, and there have been others in the past. And,

63
00:02:48.430 --> 00:02:51.370
uh, the language specification

64
00:02:51.380 --> 00:02:53.450
could allow more of those in the future.

65
00:02:54.240 --> 00:02:57.010
>> No. Awesome. Well, thanks for that tidbit. We, uh, you

66
00:02:57.010 --> 00:02:59.840
know, obviously, like Taylor said, go check back at

67
00:02:59.850 --> 00:03:02.850
our other podcast where we talked to more in depth

68
00:03:02.850 --> 00:03:05.690
about that, or feel free to check it out in this week.

69
00:03:05.700 --> 00:03:07.450
This week's edition of Haskell Weekly.

70
00:03:08.740 --> 00:03:11.550
>> Mm. So, but yeah, like I mentioned,

71
00:03:11.550 --> 00:03:14.200
that's not what we're here to talk about today.

72
00:03:14.210 --> 00:03:16.990
Instead, we're gonna be talking about maybe and

73
00:03:16.990 --> 00:03:18.060
either Right, Cam?

74
00:03:18.070 --> 00:03:21.000
>> Yeah. Yeah, I think,

75
00:03:21.010 --> 00:03:24.000
uh, you know, for those who have been in programming and

76
00:03:24.000 --> 00:03:26.910
Haskell for a period of time. You've come across

77
00:03:26.910 --> 00:03:29.730
this decision of Do I use an either here or do I use maybe

78
00:03:29.730 --> 00:03:32.670
here and today the post We're gonna be kind

79
00:03:32.670 --> 00:03:35.610
of diving more into is, you know, leaning

80
00:03:35.610 --> 00:03:38.370
more towards Hey, use either here because

81
00:03:38.380 --> 00:03:41.070
you don't wanna lose necessarily information

82
00:03:41.080 --> 00:03:43.930
and I think we can easily

83
00:03:43.940 --> 00:03:46.900
kind of navigate that by, you know,

84
00:03:46.910 --> 00:03:49.450
I mean, it's really up to you know

85
00:03:49.460 --> 00:03:51.900
what the case is, right? Like everything's different.

86
00:03:51.900 --> 00:03:54.750
Nobody when you're, you

87
00:03:54.750 --> 00:03:57.710
know, saying for input like maybe it's generally OK for

88
00:03:57.710 --> 00:03:59.630
an input like it's either there it's not

89
00:04:00.700 --> 00:04:03.370
and you can kind of, you know, but that could also work for either, Like

90
00:04:03.540 --> 00:04:06.490
it's not there and it gives you some useful

91
00:04:06.490 --> 00:04:09.300
information. So, um yeah, I

92
00:04:09.300 --> 00:04:12.110
think you know, he kind of dives in here. Um,

93
00:04:12.120 --> 00:04:15.080
do you want to kind of give what his nutshell per

94
00:04:15.080 --> 00:04:15.610
se is?

95
00:04:15.620 --> 00:04:18.380
>> Sure. And even before we get to the like,

96
00:04:18.380 --> 00:04:20.970
30,000 ft overview of this, some of the

97
00:04:20.980 --> 00:04:23.780
motivation, so maybe is

98
00:04:23.780 --> 00:04:26.730
sort of, in a way, Haskell's answer to

99
00:04:26.740 --> 00:04:29.510
null most other mainstream programming

100
00:04:29.510 --> 00:04:32.060
languages have a concept of null

101
00:04:32.060 --> 00:04:34.540
that is a valid value for any

102
00:04:34.540 --> 00:04:37.360
type. And this is frequently referred to as the billion

103
00:04:37.360 --> 00:04:40.210
dollar mistake because it causes so many

104
00:04:40.220 --> 00:04:42.850
bugs and weird program behaviors.

105
00:04:43.240 --> 00:04:46.140
And in Haskell We don't have that. And instead, if

106
00:04:46.140 --> 00:04:48.600
you had something that would be nullable in another

107
00:04:48.600 --> 00:04:50.770
language in Haskell, you model that with maybe.

108
00:04:51.140 --> 00:04:53.750
And I think the high level overview

109
00:04:53.750 --> 00:04:56.590
of Robert's, the Post author

110
00:04:56.590 --> 00:04:59.250
here of his like what he's putting forth here

111
00:04:59.260 --> 00:05:02.150
is, if you are wanting to

112
00:05:02.150 --> 00:05:05.010
return, maybe perhaps you

113
00:05:05.010 --> 00:05:08.000
should return either instead, so that if

114
00:05:08.000 --> 00:05:10.860
something does go wrong, you'll know which

115
00:05:10.860 --> 00:05:13.690
thing went wrong rather than just like, Well, something somewhere went

116
00:05:13.690 --> 00:05:16.530
wrong. Good luck, Which is better

117
00:05:16.530 --> 00:05:18.470
than a null pointer error, but

118
00:05:19.040 --> 00:05:20.690
maybe only a little bit,

119
00:05:20.700 --> 00:05:23.660
>> right? I mean, if you're parsing through some code and you're

120
00:05:23.660 --> 00:05:26.250
like, I could be these five

121
00:05:26.260 --> 00:05:29.140
possible, you know, null values or nothing

122
00:05:29.140 --> 00:05:31.600
values like which one is it? Um,

123
00:05:31.610 --> 00:05:34.390
you know, the fact that Haskell has the

124
00:05:34.390 --> 00:05:37.000
either concept really should allow us

125
00:05:37.000 --> 00:05:39.590
to at least consider it when we are

126
00:05:39.590 --> 00:05:41.570
choosing and reaching for. Maybe

127
00:05:42.040 --> 00:05:45.000
>> I will say that in our

128
00:05:45.010 --> 00:05:47.930
day to day life, developing a Web application

129
00:05:47.930 --> 00:05:50.390
at ITProTV We

130
00:05:50.400 --> 00:05:53.290
frequently do both types of conversions where

131
00:05:53.290 --> 00:05:55.840
we have a maybe value, and we want to attach

132
00:05:55.840 --> 00:05:58.560
additional information to it in the case where it's

133
00:05:58.560 --> 00:06:01.520
nothing or we have some value that already

134
00:06:01.520 --> 00:06:04.380
has extra information on it. And we want to strip that

135
00:06:04.380 --> 00:06:07.190
off to get a maybe value. And usually this is to

136
00:06:07.200 --> 00:06:10.190
meet, you know, the various contracts of Oh, we need to turn a

137
00:06:10.200 --> 00:06:12.950
We need to give a maybe to this function and we have an either or vice

138
00:06:12.950 --> 00:06:15.890
versa. Um, but very often we

139
00:06:15.890 --> 00:06:18.830
have functions that give us back a maybe, and we have

140
00:06:18.830 --> 00:06:21.830
to add extra information there that says like, Oh, we were looking at

141
00:06:21.830 --> 00:06:24.700
this field and we expected this type and it was

142
00:06:24.700 --> 00:06:27.700
that type. But we got this value which didn't parse for this

143
00:06:27.700 --> 00:06:30.650
reason. And that's way more useful for us when we're

144
00:06:30.650 --> 00:06:33.400
debugging that problem than just getting nothing

145
00:06:33.410 --> 00:06:34.760
like something went wrong.

146
00:06:35.340 --> 00:06:38.150
>> Who knows, Right? And I feel like, you

147
00:06:38.150 --> 00:06:40.810
know, there's a

148
00:06:40.810 --> 00:06:43.560
large Haskell ecosystem out there, you know,

149
00:06:43.570 --> 00:06:46.410
libraries and packages that help people solve

150
00:06:46.410 --> 00:06:49.300
problems. And, uh, you know, I

151
00:06:49.300 --> 00:06:52.220
think we've had people file

152
00:06:52.230 --> 00:06:54.600
issues and bugs on certain packages

153
00:06:54.600 --> 00:06:57.400
because this returning them, maybe. And there's some sort of failure

154
00:06:57.400 --> 00:07:00.280
that they don't have any idea to Why that happened

155
00:07:00.290 --> 00:07:02.750
on so You know, the author here kind of

156
00:07:02.750 --> 00:07:05.240
uses servant multi part as

157
00:07:05.240 --> 00:07:07.850
a, um kind of

158
00:07:08.540 --> 00:07:11.420
example to say, Hey, here's something that used to

159
00:07:11.420 --> 00:07:14.360
use Maybe now it's using on either, and it's

160
00:07:14.360 --> 00:07:15.950
honestly a better package for it.

161
00:07:16.540 --> 00:07:19.270
>> Yeah, and for those that may not be familiar.

162
00:07:19.280 --> 00:07:21.970
Ah, multi part is a part of, like,

163
00:07:21.970 --> 00:07:24.920
an HTTP form payload. So

164
00:07:24.920 --> 00:07:27.600
whenever you have a form on a HTML page and you hit

165
00:07:27.600 --> 00:07:30.530
submit that gets submitted as a multi part and then that

166
00:07:30.530 --> 00:07:33.430
has to be parsed on the server And, sometimes it's

167
00:07:33.430 --> 00:07:36.300
JSON. Sometimes it's, uh, it looks like a query

168
00:07:36.300 --> 00:07:39.210
string. But regardless of how it looks, you're parsing that.

169
00:07:39.210 --> 00:07:41.980
And if it if you can't parse it, you want to know why

170
00:07:41.980 --> 00:07:44.680
rather than just returning a 400 to the user and

171
00:07:44.680 --> 00:07:46.490
saying Sorry, try again.

172
00:07:47.140 --> 00:07:50.140
>> Yeah, I mean, that's not really giving anybody any information

173
00:07:50.140 --> 00:07:53.000
to go anywhere. I mean, you know, it's

174
00:07:53.000 --> 00:07:55.950
kind of that whole just putting somebody. You

175
00:07:55.950 --> 00:07:58.950
always telling that person to turn Right? And they're just gonna go In a

176
00:07:58.950 --> 00:07:59.440
circle?

177
00:07:59.450 --> 00:08:02.040
>> Yeah,

178
00:08:02.050 --> 00:08:04.400
and then to kind of support

179
00:08:04.410 --> 00:08:07.320
this suggested shift into

180
00:08:07.320 --> 00:08:09.620
either versus Maybe, um, he

181
00:08:09.620 --> 00:08:12.610
proposes. Or maybe I'm not sure if he's proposing this function

182
00:08:12.610 --> 00:08:15.540
or if he's talking about one that already exists called unexplain for doing that

183
00:08:15.540 --> 00:08:18.510
conversion I talked about just a minute ago where you have an either. And you

184
00:08:18.510 --> 00:08:21.090
need a maybe, um And we

185
00:08:21.090 --> 00:08:23.730
recently introduced to functions like this to

186
00:08:23.730 --> 00:08:26.470
our prelude where we call them

187
00:08:26.470 --> 00:08:29.410
note and hush and, uh, may have

188
00:08:29.410 --> 00:08:32.260
come from somewhere else again, I don't know, but they're such simple functions. They're

189
00:08:32.260 --> 00:08:35.090
easy to write, so note takes it maybe value

190
00:08:35.090 --> 00:08:37.940
and the like, um, string.

191
00:08:37.940 --> 00:08:40.910
Normally that you want to give on the error and gives you back

192
00:08:40.910 --> 00:08:43.530
an either. And then hush goes the other way. So it's a little

193
00:08:43.530 --> 00:08:44.870
evocative of how they work.

194
00:08:45.240 --> 00:08:47.160
>> It's very similar to unexplain, hush is.

195
00:08:47.840 --> 00:08:50.710
>> Right and those are very nice because that you

196
00:08:50.710 --> 00:08:53.620
can use them in line. Really? You know, succinctly

197
00:08:53.620 --> 00:08:56.130
and works out nicely. Um,

198
00:08:56.140 --> 00:08:59.070
and I think he has an interesting example here of talking

199
00:08:59.070 --> 00:09:01.910
about Aeson the Jason Library, where

200
00:09:01.910 --> 00:09:04.350
it has a bunch of different functions for doing

201
00:09:04.350 --> 00:09:07.230
decoding that return various different. You

202
00:09:07.230 --> 00:09:10.150
know, is it an either. Is it a parser? Is it a maybe, is it?

203
00:09:10.150 --> 00:09:13.000
Whatever. Um, and it feels like you

204
00:09:13.000 --> 00:09:15.840
could just have one of those, and then these note

205
00:09:15.850 --> 00:09:18.770
or hush type functions, to, you know,

206
00:09:18.780 --> 00:09:20.950
massage it in the shape you want.

207
00:09:21.840 --> 00:09:24.800
>> Mhm. Yeah. And I mean, you know, aeson's a

208
00:09:24.800 --> 00:09:27.520
good example of, a

209
00:09:27.520 --> 00:09:30.260
library that does have a lot of support for either,

210
00:09:30.270 --> 00:09:33.140
Um, whereas, you know,

211
00:09:33.150 --> 00:09:35.700
obviously they have Maybe, and I think that's kind of their

212
00:09:35.700 --> 00:09:38.380
default, but they've, you know, with the New

213
00:09:38.380 --> 00:09:41.260
Age and everybody realized Oh, yeah, we may want this

214
00:09:41.270 --> 00:09:44.000
error information passed along, You know,

215
00:09:44.010 --> 00:09:46.460
they've kind of added this either, um,

216
00:09:47.440 --> 00:09:50.410
either functions into their library.

217
00:09:50.410 --> 00:09:53.380
So much appreciated. I know. We used

218
00:09:53.390 --> 00:09:56.170
either decode a lot. Um,

219
00:09:56.540 --> 00:09:59.420
>> yeah, we use that all the time, and I think their error messages have

220
00:09:59.420 --> 00:10:02.340
gotten a lot better. And I know there used

221
00:10:02.340 --> 00:10:05.270
to be a separate package for getting better error messages

222
00:10:05.270 --> 00:10:08.070
out of aeson. And so maybe they took a page out of that

223
00:10:08.070 --> 00:10:09.650
book and rolled it into the library

224
00:10:09.650 --> 00:10:11.360
itself.

225
00:10:12.140 --> 00:10:14.820
>> Yeah, and you know, I think, uh, you know,

226
00:10:14.830 --> 00:10:17.670
aeson has, um, basic

227
00:10:17.670 --> 00:10:20.100
ways to signal a failed conversion,

228
00:10:20.110 --> 00:10:23.030
right? Whether it, you know,

229
00:10:23.040 --> 00:10:25.710
has that customary message with the either or

230
00:10:25.720 --> 00:10:28.610
just it's nothing right, which

231
00:10:28.620 --> 00:10:31.290
isn't always informative, and it kind of makes it a little difficult,

232
00:10:31.290 --> 00:10:33.140
But, you know, there's a

233
00:10:33.150 --> 00:10:35.850
certain type

234
00:10:35.850 --> 00:10:38.710
classes that maybe has that either doesn't, which I

235
00:10:38.710 --> 00:10:40.070
think we'll touch on here in a little bit.

236
00:10:40.740 --> 00:10:43.740
>> Yeah, and like you mentioned with Aeson there are

237
00:10:43.740 --> 00:10:46.450
lots of different ways. It reports errors, and I think that comes

238
00:10:46.450 --> 00:10:49.450
from under the covers. It's like a parsing library. I don't know if

239
00:10:49.450 --> 00:10:52.430
they implement their own or if they rely on one that's probably attoparsec

240
00:10:52.470 --> 00:10:55.200
or something like that button. Those parsing libraries

241
00:10:55.200 --> 00:10:57.380
often, uh, implement

242
00:10:57.390 --> 00:11:00.110
either, well, one of the type

243
00:11:00.110 --> 00:11:02.870
classes of alternative or

244
00:11:02.870 --> 00:11:05.850
monad plus, and both of those have this concept

245
00:11:05.860 --> 00:11:08.690
of like choice. Give me either this one,

246
00:11:08.690 --> 00:11:11.670
or if that one fails, give me this other one, Um,

247
00:11:11.680 --> 00:11:14.470
and as a consequence, they also have the

248
00:11:14.470 --> 00:11:17.190
identity for choice. I think it's identity where

249
00:11:17.190 --> 00:11:20.110
you say this will always fail because normally If you

250
00:11:20.110 --> 00:11:22.980
have a list of choices, what do you do if none of them match,

251
00:11:22.980 --> 00:11:25.890
then you get back. Nothing. Um and

252
00:11:25.890 --> 00:11:28.810
that's very well modeled by maybe. And like you mentioned, it

253
00:11:28.820 --> 00:11:31.630
has instances for these things. But the error

254
00:11:31.630 --> 00:11:34.590
messages are pretty bad because, like with Jason, if you're saying I want

255
00:11:34.590 --> 00:11:37.550
to parse a number or a string or I didn't get either of

256
00:11:37.550 --> 00:11:40.370
them. So the error message you get is worthless.

257
00:11:40.380 --> 00:11:41.600
I don't know.

258
00:11:41.610 --> 00:11:44.390
>> What do you really want from me, Right?

259
00:11:44.400 --> 00:11:47.040
You'll never know. Ha ha.

260
00:11:47.050 --> 00:11:50.050
>> And there are things you can do to improve this too, like. You could make your

261
00:11:50.050 --> 00:11:52.940
last case an explicit error message

262
00:11:52.940 --> 00:11:55.900
that says, you know, I was looking for one of these values and I didn't get

263
00:11:55.900 --> 00:11:58.630
any of them. And I know that some parsing libraries, like

264
00:11:58.630 --> 00:12:01.430
Megaparsec do that more or less by

265
00:12:01.430 --> 00:12:04.310
default, where they smartly figure

266
00:12:04.310 --> 00:12:06.930
out what the next token could have been and show you all the

267
00:12:06.930 --> 00:12:07.470
options.

268
00:12:07.940 --> 00:12:10.890
>> Right? Right, right. Yeah, Well,

269
00:12:10.900 --> 00:12:12.650
continuing on,

270
00:12:13.940 --> 00:12:16.850
I think we've come across this. Some in our

271
00:12:16.850 --> 00:12:19.660
own code is you know, the fact that you know monad

272
00:12:19.660 --> 00:12:22.630
fail and maybe don't really work well

273
00:12:22.630 --> 00:12:24.260
together. Uh,

274
00:12:24.270 --> 00:12:27.200
>> or they do work well together. Maybe too well,

275
00:12:27.210 --> 00:12:30.100
because fail suggests that you

276
00:12:30.100 --> 00:12:33.010
will get the error message and maybe says, Yeah, I

277
00:12:33.010 --> 00:12:35.830
implement monad fail, but I just throw that error message away.

278
00:12:35.840 --> 00:12:38.660
>> It's just like, uh, it's

279
00:12:38.660 --> 00:12:41.070
gives you a false sense of security, for sure or like

280
00:12:41.540 --> 00:12:43.670
assurance. I guess not. Security.

281
00:12:44.140 --> 00:12:47.000
>> Yeah. You feel like oh, I'm doing I'm doing my part. You

282
00:12:47.000 --> 00:12:49.880
know, I'm helping us with exception reports by

283
00:12:49.880 --> 00:12:52.760
providing this beautiful, useful error message. But

284
00:12:53.240 --> 00:12:54.220
we just throw that away

285
00:12:54.250 --> 00:12:54.860
>> Nah,

286
00:12:55.240 --> 00:12:56.250
>> Uh huh,

287
00:12:57.240 --> 00:13:00.120
Yeah, but yeah, and and kind of a related

288
00:13:00.120 --> 00:13:02.490
point is the next thing he talks about with cat maybes

289
00:13:02.490 --> 00:13:05.230
where, um, he suggests using

290
00:13:05.230 --> 00:13:08.130
partition either's instead, which lets

291
00:13:08.130 --> 00:13:11.070
you instead of throwing away the nothing's

292
00:13:11.080 --> 00:13:14.030
partition either's takes in a list of

293
00:13:14.030 --> 00:13:16.940
either's and gives you back a tuple where

294
00:13:16.940 --> 00:13:19.690
the left things are in one of them and the right things are in the

295
00:13:19.690 --> 00:13:22.480
other. This is a change we've actually

296
00:13:22.480 --> 00:13:24.760
made to a lot of the scripts that we write

297
00:13:24.770 --> 00:13:27.710
where initially we were using cat maybes

298
00:13:27.710 --> 00:13:30.590
and then either during code review or while we're actually using the

299
00:13:30.590 --> 00:13:32.370
thing we realize.

300
00:13:33.440 --> 00:13:36.440
Wait a minute. We're just dropping these values, like, maybe that's

301
00:13:36.440 --> 00:13:39.440
a problem that we need to know about. So we use partition, either's

302
00:13:39.440 --> 00:13:42.360
instead and then log them out or fail, depending on what it

303
00:13:42.360 --> 00:13:43.110
is. Exactly.

304
00:13:43.120 --> 00:13:46.030
>> You mean, maybe maybe created some issues for

305
00:13:46.030 --> 00:13:48.260
us.

306
00:13:48.840 --> 00:13:51.250
>> We got to get in at least one good pun each episode.

307
00:13:51.250 --> 00:13:54.160
>> You know, I got to I mean so far, the

308
00:13:54.170 --> 00:13:56.420
listeners haven't thrown me out yet. So that's

309
00:13:56.420 --> 00:13:57.750
semi positive

310
00:13:57.760 --> 00:14:00.520
>> Yes, maybe. may be

311
00:14:00.530 --> 00:14:01.350
problematic.

312
00:14:01.740 --> 00:14:04.160
>> Uh huh.

313
00:14:05.040 --> 00:14:08.000
Well, awesome. Yeah. I mean, I would be in favor of

314
00:14:08.000 --> 00:14:11.000
that. I mean, the nice thing is partition eithers, you know, acts the

315
00:14:11.000 --> 00:14:13.840
same way. And if you're in a situation where you don't really care about what the lefts

316
00:14:13.840 --> 00:14:16.740
say, you can just, you know, continue with the

317
00:14:16.740 --> 00:14:18.310
rights and move forward.

318
00:14:18.320 --> 00:14:21.210
>> Yep. Yeah. Pattern match on one side of that tuple And it's

319
00:14:21.210 --> 00:14:23.500
exactly the same as you called cat maybes.

320
00:14:23.510 --> 00:14:26.350
>> Yeah. All right.

321
00:14:26.940 --> 00:14:29.480
>> So the next thing he talks about is like a

322
00:14:29.480 --> 00:14:32.360
design pattern, and I don't want to spend too much

323
00:14:32.370 --> 00:14:35.350
time talking about the design pattern itself. It's called the higher

324
00:14:35.350 --> 00:14:37.980
kinded data pattern. And it's where, instead of

325
00:14:37.980 --> 00:14:40.790
defining a record with a bunch of concrete,

326
00:14:40.800 --> 00:14:43.580
um, monomorphic types for the fields,

327
00:14:43.590 --> 00:14:46.260
you parameterize the entire record

328
00:14:46.310 --> 00:14:49.190
over some container type. So the example they

329
00:14:49.190 --> 00:14:52.160
give is some person, and it has a

330
00:14:52.160 --> 00:14:54.780
type variable f. And for each field like

331
00:14:54.780 --> 00:14:57.670
name, it is of type F string and

332
00:14:57.680 --> 00:14:59.860
age's of type F int.

333
00:15:00.440 --> 00:15:02.800
And this looks a little goofy to start. But the idea

334
00:15:02.800 --> 00:15:05.760
is, when you're doing validation, you would have

335
00:15:05.760 --> 00:15:08.430
a person where f is maybe

336
00:15:08.440 --> 00:15:11.360
meaning that the values are either not there yet or didn't pass

337
00:15:11.360 --> 00:15:13.930
validation or whatever. And then once you've

338
00:15:13.940 --> 00:15:16.480
validated everything, you change that f from

339
00:15:16.480 --> 00:15:19.150
maybe to identity. And you're saying Okay, now everything is

340
00:15:19.150 --> 00:15:21.930
actually there, and this is, ah, powerful

341
00:15:21.930 --> 00:15:24.650
way. I know. In a previous episode we talked

342
00:15:24.650 --> 00:15:27.240
about, um, parse, don't validate.

343
00:15:27.250 --> 00:15:30.140
And I've used validation a lot as I've been talking about this,

344
00:15:30.140 --> 00:15:32.920
but this is a way to quote unquote parse this

345
00:15:32.920 --> 00:15:35.720
stuff by pushing this information to the type level

346
00:15:35.720 --> 00:15:38.360
and forcing yourself to prove that they're all there

347
00:15:38.940 --> 00:15:41.860
>> mhm so. Okay, so with this

348
00:15:41.870 --> 00:15:43.850
higher kinded data pattern,

349
00:15:44.340 --> 00:15:46.840
um, you know, he kind of

350
00:15:47.070 --> 00:15:49.970
launches in with maybe all the way.

351
00:15:49.980 --> 00:15:52.870
Um, and obviously in this post,

352
00:15:52.870 --> 00:15:55.740
he's kind of saying, hey, be weary of maybe maybe it's

353
00:15:55.740 --> 00:15:58.630
not the best case. Uh, so

354
00:15:58.630 --> 00:16:00.760
he starts and kind of moves towards

355
00:16:01.240 --> 00:16:03.790
you know, I guess. Using either in this I

356
00:16:03.800 --> 00:16:06.550
got a little confusing that for me for a minute. Um,

357
00:16:07.040 --> 00:16:09.750
but what do you kind of parts of the next section

358
00:16:09.750 --> 00:16:11.960
of this higher kinded data? Strict pattern.

359
00:16:13.260 --> 00:16:16.000
>> This one gets a little tricky because with

360
00:16:16.010 --> 00:16:19.010
maybe it's very easy to flip this around. So

361
00:16:19.010 --> 00:16:21.300
if you have a person where f is, maybe

362
00:16:21.600 --> 00:16:24.310
it's easy to turn that into a maybe

363
00:16:24.510 --> 00:16:27.490
person where f is identity? Because

364
00:16:27.500 --> 00:16:30.500
you try to get every field out of it.

365
00:16:30.500 --> 00:16:33.460
And if it works, you're done. Um, but

366
00:16:33.460 --> 00:16:36.290
often what you If you had a person

367
00:16:36.290 --> 00:16:38.750
where f is either string,

368
00:16:39.640 --> 00:16:42.460
you have a choice. Do you want to stop as

369
00:16:42.460 --> 00:16:45.160
soon as one thing goes wrong, or do you want to

370
00:16:45.160 --> 00:16:48.000
try to go as far as you can and collect as

371
00:16:48.000 --> 00:16:50.860
many error messages as possible and then return all of them?

372
00:16:51.240 --> 00:16:54.160
So the example I always think about here is if

373
00:16:54.160 --> 00:16:57.060
you're trying to sign up for some service and

374
00:16:57.070 --> 00:17:00.040
you load the form and then you just submit it and it comes back and

375
00:17:00.040 --> 00:17:02.970
says, Hey, first name is required like OK, cool. I'll fill

376
00:17:02.970 --> 00:17:05.880
out the first name, submit the form again. Last name is also

377
00:17:05.880 --> 00:17:08.750
required. Okay, fill that out and then, you know, do

378
00:17:08.750 --> 00:17:11.570
that three or four times you get a little frustrated, whereas if you just

379
00:17:11.640 --> 00:17:14.420
hit it once and it comes back and says all of these things are required,

380
00:17:14.430 --> 00:17:16.770
that's the difference that I'm talking about here.

381
00:17:18.140 --> 00:17:20.810
And he recommends a package called

382
00:17:20.810 --> 00:17:23.610
Barbies, which I had not heard of before. But it has a great

383
00:17:23.610 --> 00:17:26.170
description on Hackage. It says,

384
00:17:26.180 --> 00:17:29.170
Um, types that are parametric on a

385
00:17:29.170 --> 00:17:32.060
functor which is what we're talking about here. This higher kinded

386
00:17:32.060 --> 00:17:35.030
data pattern types that are parametric on

387
00:17:35.030 --> 00:17:37.860
a functor are like Barbies that have an outfit for each

388
00:17:37.860 --> 00:17:40.560
role. So maybe is an outfit. Either is an outfit,

389
00:17:40.560 --> 00:17:43.530
identity is an outfit. I just think that's a cute description of

390
00:17:43.530 --> 00:17:46.520
this. Um, but

391
00:17:46.520 --> 00:17:49.350
yeah, the package the Barbies package gives helpers for

392
00:17:49.350 --> 00:17:51.570
doing this error collection that I was just

393
00:17:51.570 --> 00:17:52.860
describing

394
00:17:53.340 --> 00:17:53.850
>> Noice.

395
00:17:55.740 --> 00:17:58.570
>> Um, so, yeah, I'm not sure I have much more to

396
00:17:58.570 --> 00:18:01.560
say about HKD. Was there any other stuff you wanted to know about it?

397
00:18:02.540 --> 00:18:05.360
>> No, I think that was good. I Yes. As I'm

398
00:18:06.180 --> 00:18:09.090
re parsing through it with what you're saying, Um,

399
00:18:09.100 --> 00:18:11.770
you know, the fact that it, you know, returns

400
00:18:11.770 --> 00:18:14.640
this either list of field info and your

401
00:18:14.640 --> 00:18:17.070
example was great. So I really appreciate that.

402
00:18:17.740 --> 00:18:20.630
>> Yeah. Happy to help. Um,

403
00:18:20.640 --> 00:18:23.550
And then he, uh, he goes on the post

404
00:18:23.550 --> 00:18:26.290
author here. Goes on to talk about Java

405
00:18:26.290 --> 00:18:29.130
beans, which are I wasn't aware of this as,

406
00:18:29.130 --> 00:18:31.660
like, a thing. I have worked with Java, but it's been a long time.

407
00:18:32.040 --> 00:18:34.990
And, uh, apparently java beans air, like a

408
00:18:34.990 --> 00:18:37.170
class that can have an empty

409
00:18:37.940 --> 00:18:38.270
thing.

410
00:18:38.270 --> 00:18:38.820
>> Instance,

411
00:18:38.830 --> 00:18:41.670
>> Yeah. Instance. Or like, a default value or

412
00:18:41.670 --> 00:18:44.360
something like that. Um, but I had a hard time

413
00:18:44.360 --> 00:18:46.560
following this section because I

414
00:18:47.040 --> 00:18:49.850
couldn't get these things to type. Check in my head with the

415
00:18:49.850 --> 00:18:52.670
GHC that's running in my head. And then I tried with a real

416
00:18:52.670 --> 00:18:55.110
GHC and it wouldn't type check there either,

417
00:18:55.110 --> 00:18:58.100
so I don't know what to say about this doesn't make

418
00:18:58.100 --> 00:18:58.680
sense to me.

419
00:18:59.340 --> 00:19:02.170
>> Yeah. I mean, you know, one would

420
00:19:02.170 --> 00:19:05.090
think that, You know, if you

421
00:19:05.090 --> 00:19:07.920
have a person of the

422
00:19:07.920 --> 00:19:10.730
maybe functor... Right, functor? Maybe's a functor?

423
00:19:10.740 --> 00:19:13.130
Okay. I want to make sure

424
00:19:13.140 --> 00:19:16.060
I'm not mis-speaking here. Because I know someone on the Internet will tell me

425
00:19:16.060 --> 00:19:18.950
I'm wrong, but that's okay. Uh, you know, in person of

426
00:19:18.950 --> 00:19:21.840
identity, then you

427
00:19:21.840 --> 00:19:24.170
try to mix them together. That's not

428
00:19:24.540 --> 00:19:27.460
kind of work. I mean, and that's that whole compiler thing in

429
00:19:27.460 --> 00:19:29.760
your head. Not working. Um,

430
00:19:30.540 --> 00:19:33.070
I mean, if you wanted to, you could run, maybe and

431
00:19:33.080 --> 00:19:35.770
have it to, you know, return just 10 rather than

432
00:19:35.780 --> 00:19:36.960
identity.

433
00:19:37.640 --> 00:19:40.520
>> Yeah, but then the whole example would be different.

434
00:19:40.580 --> 00:19:43.570
>> So a little, a little more to

435
00:19:43.570 --> 00:19:46.400
be desired. Here. Maybe there's just something we're missing or

436
00:19:46.400 --> 00:19:49.120
misreading. Um, so

437
00:19:49.130 --> 00:19:51.610
yeah, uh, no, I

438
00:19:51.610 --> 00:19:53.370
think you know, that section was

439
00:19:55.540 --> 00:19:58.470
informative, but still a little confusing.

440
00:19:58.470 --> 00:20:00.760
So we'll keep moving

441
00:20:01.740 --> 00:20:04.290
so. When we were kind of prepping for this

442
00:20:04.290 --> 00:20:07.060
show, we talked. We kind of stumbled

443
00:20:07.060 --> 00:20:09.840
across this next section, which is the maybe first

444
00:20:09.840 --> 00:20:11.850
monoid fields.

445
00:20:12.240 --> 00:20:15.170
And we were

446
00:20:15.940 --> 00:20:18.340
also a little like first And then we

447
00:20:18.340 --> 00:20:21.070
realized first was just really a wrapper around maybe,

448
00:20:21.440 --> 00:20:24.290
Um uh, and you know, then

449
00:20:24.290 --> 00:20:26.930
things got really interesting when we, uh, made a grandpa

450
00:20:26.940 --> 00:20:29.940
toddler That happened somewhere later in this

451
00:20:29.940 --> 00:20:31.950
example.

452
00:20:32.340 --> 00:20:35.130
>> Yeah. So, like you mentioned first is a new

453
00:20:35.130 --> 00:20:38.100
type wrapper around maybe. And the thing

454
00:20:38.100 --> 00:20:41.010
that it does for you is pick. Um, when

455
00:20:41.010 --> 00:20:43.570
you do like a semi group append that

456
00:20:43.570 --> 00:20:45.770
diamond operator or mappend either one,

457
00:20:46.140 --> 00:20:49.090
Uh, it will give you the first value.

458
00:20:49.090 --> 00:20:51.700
That is just something.

459
00:20:51.780 --> 00:20:54.770
So if you're one on the left, is a nothing? You'll get the

460
00:20:54.770 --> 00:20:57.660
one on the right, And if the one on the left is a just, then

461
00:20:57.660 --> 00:21:00.280
you'll get the one on the left, regardless of what the two values are. So it

462
00:21:00.280 --> 00:21:03.210
doesn't smash them together, like with strings or add

463
00:21:03.210 --> 00:21:06.160
them together, like with sum or any of that stuff.

464
00:21:06.640 --> 00:21:09.170
And this curious

465
00:21:09.180 --> 00:21:11.880
grandpa toddler value is where they take

466
00:21:11.890 --> 00:21:14.870
two people values and smush

467
00:21:14.870 --> 00:21:17.570
them together using this first concept. And you

468
00:21:17.570 --> 00:21:20.080
can end up with some weird data Where,

469
00:21:20.090 --> 00:21:22.850
uh, yeah, it's just

470
00:21:22.850 --> 00:21:25.720
like, you know, pretty much arbitrarily grabbing fields from

471
00:21:25.720 --> 00:21:28.500
one and the other and pushing them together.

472
00:21:28.510 --> 00:21:31.260
>> At that point, you get a grandpa or you get a some

473
00:21:31.270 --> 00:21:34.170
person with the name Grandpa and an age of one. I

474
00:21:34.180 --> 00:21:36.210
mean, they must have started when they were really, really

475
00:21:36.210 --> 00:21:37.770
young.

476
00:21:38.240 --> 00:21:41.190
>> Um and I'll just say for this we have

477
00:21:41.190 --> 00:21:43.950
done this in our code base, a fair amount where we have

478
00:21:43.950 --> 00:21:46.840
custom data types, that we have

479
00:21:46.840 --> 00:21:49.320
semi group instances to combine them

480
00:21:49.320 --> 00:21:52.100
together. But usually we implement

481
00:21:52.100 --> 00:21:55.020
those instances by hand rather than

482
00:21:55.020 --> 00:21:57.890
leaning on these, um, kind of convenience new

483
00:21:57.890 --> 00:22:00.740
type qrappers that the semi group and monoid modules

484
00:22:00.740 --> 00:22:03.560
expose like first and last and product and all this

485
00:22:03.560 --> 00:22:06.500
other stuff. Um, so this hasn't been a

486
00:22:06.500 --> 00:22:08.670
problem for us in practice. And

487
00:22:08.680 --> 00:22:11.390
also we don't implement them for, like our quote

488
00:22:11.390 --> 00:22:14.210
unquote business objects like person

489
00:22:14.210 --> 00:22:16.450
or whatever. Instead, it's usually for

490
00:22:16.460 --> 00:22:19.240
configuration or some type of aggregation that we're building

491
00:22:19.240 --> 00:22:22.220
up. So I do see

492
00:22:22.220 --> 00:22:24.670
that this is a problem, but we haven't

493
00:22:24.670 --> 00:22:25.470
experienced it,

494
00:22:25.840 --> 00:22:28.460
>> right? Doesn't mean it's not out there. It's just

495
00:22:28.470 --> 00:22:31.380
firsthand, very little like, Yeah, it doesn't seem like a problem

496
00:22:31.380 --> 00:22:34.290
to us. But because we don't use that, so

497
00:22:34.290 --> 00:22:36.940
another big thing for you

498
00:22:36.940 --> 00:22:39.850
know that maybe has going for it is the

499
00:22:39.850 --> 00:22:42.760
fact that it has, you know, You know, we spoke

500
00:22:42.760 --> 00:22:45.670
earlier about having alternative instance and having more instances

501
00:22:45.670 --> 00:22:48.320
than either, Uh, which

502
00:22:48.330 --> 00:22:51.290
allows to be a little easier to work with, because you're like, Oh, yeah, it's got the

503
00:22:51.290 --> 00:22:54.010
instance I need here. I'll just go with maybe over either,

504
00:22:54.020 --> 00:22:56.770
rather than trying to create your own alternative

505
00:22:56.770 --> 00:22:57.760
instance for either.

506
00:22:58.140 --> 00:23:01.140
>> Yeah, if you want to either write code,

507
00:23:01.150 --> 00:23:04.040
that is polymorphic or use code.

508
00:23:04.040 --> 00:23:07.000
That's polymorphic than it turns out that you can use maybe

509
00:23:07.000 --> 00:23:08.760
a lot more often than you can use, either.

510
00:23:09.640 --> 00:23:12.540
And I think that's a good segue into the next section.

511
00:23:12.540 --> 00:23:15.430
And almost the last section, which is uh, we've

512
00:23:15.430 --> 00:23:18.420
spent this whole time trashing. Maybe. But when is the good

513
00:23:18.420 --> 00:23:19.370
time to use? Maybe

514
00:23:19.940 --> 00:23:21.860
>> Mm. Oh, good old. Maybe

515
00:23:22.640 --> 00:23:25.210
right. And, you know, we kind of touched on it in the beginning, right?

516
00:23:25.220 --> 00:23:28.040
Um, you know, the authors here says he

517
00:23:28.040 --> 00:23:30.600
follows a old design principle

518
00:23:30.600 --> 00:23:33.530
called Postel's Law. Where

519
00:23:33.530 --> 00:23:36.270
you know, lenient input strict

520
00:23:36.280 --> 00:23:39.040
output. Um, right. You know, things that

521
00:23:39.050 --> 00:23:41.820
can be put input to the system can be more flexible than

522
00:23:41.820 --> 00:23:43.450
what returned from the system,

523
00:23:44.240 --> 00:23:47.160
>> right? So in this particular case,

524
00:23:47.160 --> 00:23:50.120
that means like using either for your input

525
00:23:50.120 --> 00:23:53.100
would be more strict because you would be requiring people to

526
00:23:53.100 --> 00:23:55.670
give you this error information.

527
00:23:56.130 --> 00:23:59.060
But with a maybe you're just saying I

528
00:23:59.060 --> 00:24:01.980
need to know whether it's there or not. I don't need to know why it wasn't

529
00:24:01.980 --> 00:24:04.270
there, so that's a little more lenient.

530
00:24:05.340 --> 00:24:06.980
>> So go maybe

531
00:24:06.980 --> 00:24:09.950
woo!

532
00:24:09.960 --> 00:24:12.890
>> I do think it's funny that he explicitly mentions data

533
00:24:12.890 --> 00:24:15.610
dot map. Look up as somewhere. That's probably

534
00:24:15.610 --> 00:24:18.460
fine to use. Maybe because for

535
00:24:18.460 --> 00:24:21.370
me, that's one place where I want either. And when I talk about

536
00:24:21.370 --> 00:24:24.330
in our code base, where we decorate, maybe values with error

537
00:24:24.330 --> 00:24:27.160
information, it's often on this where we're doing

538
00:24:27.160 --> 00:24:30.070
three or four look ups in a row, and we want to know which

539
00:24:30.070 --> 00:24:32.970
one failed. And it's really convenient to say, Oh, I couldn't find this

540
00:24:32.970 --> 00:24:35.960
key rather than just getting back nothing.

541
00:24:36.740 --> 00:24:39.560
>> Yeah, maybe that's a future enhancement.

542
00:24:40.140 --> 00:24:42.660
>> Mhm. Yeah, we'll have another.

543
00:24:43.040 --> 00:24:45.670
Yeah, well, we end up doing a lot of note. Look

544
00:24:45.670 --> 00:24:48.380
up. Using the helper function we talked about e

545
00:24:48.390 --> 00:24:50.880
>> mean at this point we should just probably, you know,

546
00:24:50.890 --> 00:24:53.760
pull a new instance of look up into our prelude

547
00:24:53.760 --> 00:24:55.270
that does that

548
00:24:55.270 --> 00:24:56.060
>> Yeah that has that on there

549
00:24:56.070 --> 00:24:59.070
>> Yeah, probably could make life a little

550
00:24:59.070 --> 00:25:01.870
easier. But, you know, note.

551
00:25:01.880 --> 00:25:04.460
Look up. isn't the worst thing in the world either,

552
00:25:04.470 --> 00:25:07.440
but, Well, awesome. Yeah, I think

553
00:25:07.440 --> 00:25:10.400
that was, uh, some Good

554
00:25:10.400 --> 00:25:13.160
cases for using, maybe. And, you know, overall,

555
00:25:13.640 --> 00:25:16.470
maybe either is the way to go, but, you know, maybe has its

556
00:25:16.470 --> 00:25:18.470
place. That's why it's in the ecosystem.

557
00:25:19.040 --> 00:25:21.560
>> This is a compelling argument to me, and I've

558
00:25:21.770 --> 00:25:24.670
found I haven't, you know, crystallized this opinion

559
00:25:24.670 --> 00:25:27.610
myself or thought too much about it before. But reading

560
00:25:27.610 --> 00:25:30.320
through this post, I was like, Yeah, you know, most of the time I would prefer

561
00:25:30.320 --> 00:25:33.100
something that dealt with either or something.

562
00:25:33.100 --> 00:25:35.900
isomorphic to either rather than maybe so that

563
00:25:35.900 --> 00:25:37.670
when something goes wrong, I'll know why.

564
00:25:38.440 --> 00:25:40.850
>> Yeah. Yeah. So

565
00:25:41.340 --> 00:25:43.850
to kind of recap the

566
00:25:43.850 --> 00:25:46.740
author's causes for thinking, you know, for

567
00:25:46.740 --> 00:25:49.720
saying it's overused. Uh, yeah. He

568
00:25:49.720 --> 00:25:52.500
says, you know, using maybe is simpler than either,

569
00:25:52.510 --> 00:25:55.470
um, you know, coding with Maybe it's

570
00:25:55.480 --> 00:25:58.410
terser, which is a fun, weird

571
00:25:58.420 --> 00:26:01.000
terser uh, maybe

572
00:26:01.000 --> 00:26:03.950
is more expressive, really having more

573
00:26:03.960 --> 00:26:06.860
instances available to it on. And then you know,

574
00:26:08.340 --> 00:26:11.310
the sophisticated abstractions can can

575
00:26:11.310 --> 00:26:14.070
obscure the common sense. But,

576
00:26:14.440 --> 00:26:17.210
you know, use maybe it's gonna make

577
00:26:17.210 --> 00:26:20.170
it do what you want. It can

578
00:26:20.170 --> 00:26:23.090
make it do what you want. But you may also be missing information and

579
00:26:23.090 --> 00:26:25.360
losing out on things you expect to be there.

580
00:26:25.840 --> 00:26:28.600
>> Yeah, I think this ties into the previous one where, since

581
00:26:28.600 --> 00:26:31.510
maybe has more instances, you can use it with more

582
00:26:31.510 --> 00:26:34.180
abstractions, and it will

583
00:26:34.180 --> 00:26:37.140
probably all type check. But you may end up with something that's very

584
00:26:37.140 --> 00:26:39.670
confusing either to use or to debug.

585
00:26:40.840 --> 00:26:43.670
>> Precisely. Well,

586
00:26:43.680 --> 00:26:46.230
awesome, Taylor. Well, thanks for being on the show with me

587
00:26:46.230 --> 00:26:49.160
today. Thank you. Listeners for tuning in.

588
00:26:49.640 --> 00:26:52.140
Um, Taylor, where can they find

589
00:26:52.140 --> 00:26:53.570
us?

590
00:26:53.940 --> 00:26:56.690
>> Well, uh, they could probably just google for Haskell

591
00:26:56.690 --> 00:26:59.610
weekly. That might be the easiest way, but if you want to go straight

592
00:26:59.610 --> 00:27:01.430
to the source, our website is

593
00:27:01.430 --> 00:27:04.110
HaskellWeekly.News We're on

594
00:27:04.110 --> 00:27:06.690
Twitter. Our handle is Haskell Weekly. Were

595
00:27:06.690 --> 00:27:09.460
on Reddit. Same handle were on github,

596
00:27:09.470 --> 00:27:12.440
same handle. And if you want

597
00:27:12.440 --> 00:27:15.440
to suggest something, to us, you could send an email

598
00:27:15.450 --> 00:27:15.830
to

599
00:27:15.830 --> 00:27:18.560
into@HaskellWeekly.News

600
00:27:19.240 --> 00:27:20.990
>> They can't find us on MySpace?

601
00:27:21.840 --> 00:27:24.410
>> We had to take down our MySpace page.

602
00:27:24.420 --> 00:27:26.350
>> Just Yeah.

603
00:27:26.740 --> 00:27:29.250
Okay. That's okay, though, because

604
00:27:29.260 --> 00:27:31.400
Haskell Weekly podcast is brought to you by

605
00:27:31.410 --> 00:27:34.280
ITProTV the e-learning platform for

606
00:27:34.280 --> 00:27:36.810
IT professionals. And also our employer

607
00:27:36.820 --> 00:27:39.500
and Thank them for letting us do such an

608
00:27:39.500 --> 00:27:42.440
incredible show. Uh, they're

609
00:27:42.440 --> 00:27:45.210
also very generous because they would love to offer all of our

610
00:27:45.210 --> 00:27:48.190
listeners a 30% discount code

611
00:27:48.200 --> 00:27:50.820
for the lifetime of the subscription by using

612
00:27:50.830 --> 00:27:53.500
HaskellWeekly30 at check

613
00:27:53.500 --> 00:27:56.290
out. And that will get you 30% off the lifetime of

614
00:27:56.300 --> 00:27:58.200
that subscription. So

615
00:27:58.210 --> 00:28:00.650
go check it

616
00:28:00.660 --> 00:28:02.440
out.

617
00:28:02.450 --> 00:28:05.200
>> Yeah, and I think that will do it for us this

618
00:28:05.200 --> 00:28:07.070
week. See you next week.

619
00:28:07.540 --> 00:28:08.080
>> Peace
