簡體   English   中英

如何在 FP 中管理 monad,特別是在 fp-ts 中

[英]How to manage monads in FP and specially in fp-ts

我對函數式編程和特別是fp-ts庫很fp-ts

我的問題包括兩部分:

  1. 我看到了一種將 Monads 從一種類型轉換為另一種類型的模式,例如從TaskIO ,反之亦然,我們如何管理這種情況,我們應該始終保持在一個類型上,還是應該隨着鏈的繼續而改變?
  2. 如何簡單地使打字稿遵循這些從一個到另一個的類型更改?

例如,假設我們有幾個函數,我們想將它們組合在一起,如下所示,我知道這個例子可能不太實用,但它可以達到目的。

declare function getRnd(min: number, max: number): IO<number>; // Returns a random number within the range
declare function getPage(pageNo: number): TaskEither<Error, string>; // Make an Http request
declare function getLinks(pageContent: string): Option<string[]>; // Returns some links

// Let's say we wanna get a random page number and then return the links on it
// How do we compose these functions?
const getPageLinks = pipe(
  getRnd(2, 4),
  IO.chain(getPage), // I'm pretty sure TS will yells at me here
  TaskEither.chain(getLinks),
  log, // ?
)

1.) 將 Monad 從一種類型轉變為另一種類型,我們如何管理這一點,我們應該始終保持在一種類型上,還是應該隨着鏈的繼續而改變?

您想要某種(自然)轉換IO切換到Task / TaskEither 反過來對我來說沒有意義,因為異步效果無法轉換為同步效果。

chain保留結構 所以getPage IO.chain(getPage)中的IO.chain(getPage)需要一個簽名number -> IO<whatever> 您可以改為使用map添加額外的嵌套層,例如:

pipe(getRnd(2, 4), IO.map(getPage)); // I.IO<TE.TaskEither<Error, string>>

一般來說,方法沒有對錯之分,只看目的。 請注意,嵌套的數據類型越多,處理內部值就越復雜。 具有代數結構的函數式編程的一部分是避免在源頭進行不必要的嵌套。

在您的情況下,將所有內容合並到一個統一的TaskEither中確實TaskEither - 類型IO<TaskEither<...>>TaskEither<...>相比,您不會有任何優勢。

2.) 如何簡單地讓打字稿跟隨這些從一種到另一種類型的變化?

您可以使用TaskEither.rightIOIO轉換為TaskEither ( CodeSandbox ):

import { taskEither as TE, io as I, option as O, pipeable as P, either as E } from "fp-ts";

declare function log<T>(t: T): I.IO<T>;

const getPageLinks = P.pipe(
  getRnd(2, 4),
  TE.rightIO,
  TE.chain(getPage),
  TE.map(getLinks),
  TE.chain(v => TE.rightIO(log(v)))
); // TE.TaskEither<Error, O.Option<string[]>>

這個也有效,因為 TS 使用結構類型(但我會推薦前者):

const getPageLinks2 = P.pipe(
  getRnd(2, 4),
  I.chain(getPage), // this also works
  I.map(v => v.then(vv => E.either.map(vv, getLinks))),
  I.chain(log)
); // I.IO<Promise<E.Either<Error, O.Option<string[]>>>>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM