美文网首页代码改变世界
函数式编程基本概念理解一: Semigroup,Monoid

函数式编程基本概念理解一: Semigroup,Monoid

作者: jimson_ma | 来源:发表于2023-05-16 23:03 被阅读0次

    实践函数式编程有几个概念是抽象的,但也是基础的,能够正确的理解它们,决定着我们如何更好的使用函数式编程。本文以 FP-TS 为例描述下我对这些概念的理解。

    文中大写字符代表一个类型(一组值的集合), 小写字符代表一个值。


    Semigroup (半群)


    Semigroup 是指一个类型联合一个二元操作*,满足以下的规律:

    1. 对于 A 中的任何 a, b, 通过该操作 *得到的 c 也属于 A, 即 a * b = ca,b,c同属于类型 A.
    2. 该操作满足结合律,即 (a * b) * c = a * (b * c)

    我们就称他们为Semigroup

    比如我们知道的自然数和加法 +就是满足这个规律的。自然数和乘法 x也是满足的。但是自然数和减法 -就不满足了,两个自然数相减可能是负数,不是自然数,同时减法也不满足结合律。 同样对于字符串和 + 也是满足的。布尔类型和 && 也满足。可以称之为自然数和加法构成的半群,自然数和乘法构成的半群,字符串和 +构成的半群,布尔类型和 && 构成的半群。

    在 FP-TS 中定义如下,操作 *concat

    interface Semigroup<A> {
      concat: (x: A, y: A) => A
    }
    
    concat(concat(x, y), z) == concat(x, concat(y, z)); // true
    
    

    当我们在逻辑中需要合并等功能时,考虑可否能够使用Semigroup。 它也是我们的功能可否并行执行的基础。

    可以自定义Semigroup:

    const semigroupSum: Semigroup<number> = {
      concat: (x, y) => x + y
    }
    

    Monoid (幺半群)


    延续上面的内容,如果存在一个 Semigroup<A> ,可以找到一个唯一的一个值 e,使其能够满足:

    1. concat(x, e) == concat(e, x) == x
    2. e 属于类型 A

    e 我们称之为幺元,所以可以理解 Monoid (幺半群) 为存在 幺元Semigroup (半群)

    比如正整数和乘法就能构成Monoid (幺半群)1 就是那个幺元,但是正整数和加法就不行,找不到幺元,只能称之为Semigroup (半群),因为它的幺元0, 如果要自然数和加法,则可以是Monoid (幺半群) 。同理字符串和 +里的空字符串''是它的幺元。数组中的空数组等都可以做幺元

    在 FP-TS 中定义如下,操作 *concat

    interface Monoid<A> extends Semigroup<A> {
      readonly empty: A
    }
    

    可以自定义Monoid

    /** number `Monoid` under addition */
    const monoidSum: Monoid<number> = {
      concat: (x, y) => x + y,
      empty: 0
    }
    
    /** number `Monoid` under multiplication */
    const monoidProduct: Monoid<number> = {
      concat: (x, y) => x * y,
      empty: 1
    }
    
    const monoidString: Monoid<string> = {
      concat: (x, y) => x + y,
      empty: ''
    }
    
    /** boolean monoid under conjunction */
    const monoidAll: Monoid<boolean> = {
      concat: (x, y) => x && y,
      empty: true
    }
    
    /** boolean monoid under disjunction */
    const monoidAny: Monoid<boolean> = {
      concat: (x, y) => x || y,
      empty: false
    }
    

    参考:
    https://dev.to/gcanti/getting-started-with-fp-ts-semigroup-2mf7
    https://dev.to/gcanti/getting-started-with-fp-ts-monoid-ja0

    相关文章

      网友评论

        本文标题:函数式编程基本概念理解一: Semigroup,Monoid

        本文链接:https://www.haomeiwen.com/subject/mpnbsdtx.html