gcanti / flow-static-land

[DEPRECATED, please check out fp-ts] Implementation of common algebraic types in JavaScript + Flow
MIT License
408 stars 22 forks source link

Monoid Implementation Question #24

Closed mwalkerwells closed 7 years ago

mwalkerwells commented 7 years ago

This may be a n00b question, but what is the reason getSemigroup, getMonoid, _get_Setoid are implemented differently than map / Functor?

Monoid:

export function getSemigroup<A>(semigroup: Semigroup<A>): Semigroup<Maybe<A>> {
  return {
    concat(fx, fy) {
      const x = prj(fx)
      const y = prj(fy)
      if (x == null) {
        return fy
      }
      if (y == null) {
        return fx
      }
      return of(semigroup.concat(x, y))
    }
  }
}

Map / Functor

export function map<A, B>(f: (a: A) => B, fa: Maybe<A>): Maybe<B> {
  const a = prj(fa)
  return a == null ? Nothing : inj(f(a))
}

It seemed weird that we're not type checking for Monoid...making me wonder how to implement it differently or better understand why it's not possible.

Type Checks:

if (false) { // eslint-disable-line
  ({
    map,
    ap,
    of,
    chain,
    reduce,
    alt,
    pempty,
    extend
  }: Monad<IsMaybe> &
     Foldable<IsMaybe> &
     Alt<IsMaybe> &
     Plus<IsMaybe> &
     Alternative<IsMaybe> &
     Extend<IsMaybe>)
}
gcanti commented 7 years ago

Maybe<A> is a semigroup if A is a semigroup, so you need to pass in a type class instance for A

function getSemigroup<A>(semigroup: Semigroup<A>): Semigroup<Maybe<A>>
//                           ^
//                           +--- type class instance for `A` 

the signature (and the implementation) is almost a word by word translation of the corrsponding PureScript definition (cfr purescript-maybe)

instance semigroupMaybe :: Semigroup a => Semigroup (Maybe a) where
  append Nothing y = y
  append x Nothing = x
  append (Just x) (Just y) = Just (x <> y)

Note the "Semigroup a =>" type constraint.

It seemed weird that we're not type checking for Monoid

Actually we are type checking: getSemigroup returns a Semigroup<Maybe<A>>

mwalkerwells commented 7 years ago

Eh, reading this, now it seems so obvious:

Maybe is a semigroup if A is a semigroup

Thanks for the clarification!