@@ -188,82 +188,21 @@ If the value is fetched, input, received, selected, than use ``IO`` container.
188
188
189
189
Most web applications are just covered with ``IO ``.
190
190
191
- What is the difference between IO[Result[A, B]] and Result[IO[A], B] ?
192
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
191
+ Why IO should be at the top level of composition ?
192
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
193
193
194
194
As we state in :ref: `Composition docs <composition >`
195
195
we allow to compose different containers together.
196
196
197
- That's where this question raises:
198
- should I apply ``IO `` to all ``Result `` or only to the value part?
199
-
200
- Short answer: we prefer ``IO[Result[A, B]] ``
197
+ We prefer ``IO[Result[A, B]] ``
201
198
and sticking to the single version allows better composition.
199
+ The same rule is applied to ``Maybe `` and all other containers we have.
202
200
203
- Long answer. Let's see these two examples:
204
-
205
- .. code :: python
206
-
207
- from returns.io import IO , impure
208
- from returns.result import Result, safe
209
-
210
- def get_user_age () -> Result[IO [int ], ValueError ]:
211
- # Safe, but impure operation:
212
- prompt: IO [str ] = impure(input )(" What's your age?" )
213
-
214
- # Pure, but unsafe operation:
215
- return safe(int )(prompt)
216
-
217
- In this case we return ``Result[IO[int], ValueError] ``,
218
- since ``IO `` operation is safe and cannot throw.
219
-
220
- .. code :: python
221
-
222
- import requests
223
- from returns.io import IO , impure
224
- from returns.result import Result, safe
225
-
226
- @impure
227
- @safe
228
- def get_user_age () -> IO [Result[int , Exception ]]:
229
- # We ask another micro-service, it is impure and can fail:
230
- return requests.get(' https://...' ).json()
231
-
232
- In this case the whole result is marked as impure.
233
- Since its failures are impure as well.
234
-
235
- What is the difference between IO[Maybe[A]] and Maybe[IO[A]]?
236
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
237
-
238
- The similar question is about ``IO `` and ``Maybe `` composition.
239
- Let's illustrate it with the code example:
240
-
241
- .. code :: python
242
-
243
- from returns.maybe import Maybe, Nothing
244
- from returns.io import IO
245
-
246
- def maybe_ask_user (should_ask : bool ) -> Maybe[IO [str ]]:
247
- if should_ask:
248
- return Maybe.new(IO(input (' Asking!' )))
249
- return Nothing
250
-
251
- In this example ``IO `` might not happen at all.
252
-
253
- .. code :: python
254
-
255
- from returns.maybe import Maybe, Nothing
256
- from returns.io import IO
257
-
258
- def ask_user () -> IO [Maybe[str ]]:
259
- prompt = input (' Asking!' )
260
- if prompt:
261
- return Maybe.new(IO(prompt))
262
- return IO(Nothing)
201
+ Composing ``IO `` at the top level is easier
202
+ because you can ``join `` things easily.
263
203
264
- In this second case, we always do ``IO ``, but we return ``Nothing ``
265
- if user inputs an empty string
266
- (because we need this business logic for some reason).
204
+ And other containers not always make sense.
205
+ If some operation performs ``IO `` it should mark all internals.
267
206
268
207
Why can't we unwrap values or use @pipeline with IO?
269
208
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0 commit comments