Где аппликатив в моей реализации обхода Javascript?
Я пытался понять Хаскелла traverse
функции и реализовать его в Javascript, но я застрял. Когда я смотрю на его тип (Functor t, Foldable t, Applicative f) => (a -> f b) -> t a -> f (t b)
Я поняла что мне нужно <$>
(map
в JS), <*>
(ap
в JS) и fold
для того, чтобы реализовать это.
Я придумал следующий код:
// Church encoded Identity newtype
const Ident = x => f => f(x);
const traverse = map => ft => tx => map(y => Ident(y)) (tx(x => ft(x)));
// list functor
map = f => xs => xs.map(f);
// helper
I = x => x;
// data
idA = Ident(1);
idB = Ident(null);
// and run
const r1 = traverse(map) (x => x === null ? [] : [x]) (idA); // [Ident(1)]
const r2 = traverse(map) (x => x === null ? [] : [x]) (idB); // []
console.log(r1 [0] (I)); // 1
console.log(r2); // []
Так как я использовал Ident
а также Array
тип упрощается до (a -> [b]) -> Ident a -> [Ident b]
, traverse
запускает эффект при перестройке структуры данных. Если я не ошибаюсь, можно наблюдать недетерминированный эффект функтора списка в моем примере.
Но где аппликатив? И почему проходимым должен быть функтор? Это просто совпадение, что я не нуждался в них для своего эскиза?