Este é um transformador de mônada válido em Javascript?

Para entender melhor os transformadores de mônada, implementei um. Como o Javascript é digitado dinamicamente, não imito construtores de tipo ou de dados, mas declaro apenas objetos Javascript antigos simples, que contêm as funções estáticas correspondentes para formar um monad / transformador específico. A ideia subjacente é aplicar esses métodos a um valor / valores em um tipo de contêiner. Tipos e recipientes são separados por assim dizer.

Arrays pode conter qualquer número de elementos. É trivial estenderArrays para que eles implementem a interface de mônada.Arrays também pode representar as duas variantes domaybe tipo. Um vazioArray corresponde anothing. AArray com um único elemento corresponde ajust(a). Consequentemente vou usarArrays como meu tipo de contêiner. Observe que esta é uma implementação rápida e suja apenas para aprender:

const array = {
  of: x => Array.of(x),
  map: f => ftor => ftor.map(f),
  ap: ftor => gtor => array.flatten(array.map(f => array.map(f) (gtor)) (ftor)),
  flatten: ftor => ftor.reduce((xs, y) => xs.concat(y), []),
  chain: mf => ftor => array.flatten(array.map(mf) (ftor))
}

const maybe = {
  of: array.of,
  empty: () => [],
  throw: ftor => { if (ftor.length > 1) throw Error("indeterministic value"); return ftor },
  map: f => ftor => maybe.throw(ftor).map(f),
  ap: ftor => gtor => maybe.flatten(maybe.map(f => maybe.map(f) (gtor)) (ftor)),
  flatten: array.flatten,
  chain: mf => ftor => maybe.flatten(maybe.map(mf) (ftor)),
  T: M => {
    return {
      of: x => M.of(maybe.of(x)),
      empty: () => M.of(maybe.empty()),
      map: f => ftor => M.map(gtor => maybe.map(f) (gtor)) (ftor),
      ap: ftor => gtor => M.flatten(M.map(htor => M.map(itor => maybe.ap(htor) (itor)) (gtor)) (ftor)),
      flatten: maybe.flatten,
      chain: mf => ftor => M.chain(gtor => maybe.chain(mf) (gtor)) (ftor)
    };
  }
};

Agora eu combino um talvez transformador com a matriz monádica para obter uma mônada que possa suportararrays demaybes.

const arraym = maybe.T(array);

const add = x => y => x + y;
const addm = x => y => [x + y];
const arrayOfMaybes = [[1],[],[3]]

Quando eu tratoarraym como um aplicador funcional, tudo funciona como esperado:

// yields: [[11],[],[13]] as expected
arraym.ap(arraym.map(add) (arrayOfMaybes)) (arraym.of(10));

No entanto, quando eu aplicochain algo der errado:

// yields: [11,13] but [[11],[13]] expected
arraym.chain(x => arraym.chain(y => addm(x) (y)) (arrayOfMaybes)) ([[10]])

É a causa deste problema

que este não é um transformador de mônada válido?que a maneira como aplico a cadeia está errada?que minha expectativa em relação ao resultado está errada?

questionAnswers(1)

yourAnswerToTheQuestion