Я играю на следующих уроках теории категорий Бартоша Милевского на YouTube.Он описывает функторы Const и Identity как «базовые» функторы, которые могут быть получены из (вероятно, либерального перефразирования с моей стороны).
Моя проблема, реализовав версию функтора ES6 + / fantasy-land (не важно), появляется, как только я начинаю интегрироваться с библиотекой Sanctuary для карты и канала.
Реализация довольно проста
const {map: flMap, extract } = require('fantasy-land');
const getInstance = (self, constructor) =>
(self instanceof constructor) ?
self :
Object.create(constructor.prototype) ;
const Identity = function(x){
const self = getInstance(this, Identity)
self[flMap] = f => Identity(f(x))
self[extract] = () => x
return Object.freeze(self)
}
Вот несколько простых примеров использования (так как я также работал с линзами для получения ионов)
// USAGE
const {map, pipe, curry} = require("sanctuary")
const extractFrom = x => x[extract]()
const setter = (f, x) => (pipe([
Identity,
map(f),
extractFrom
])(x))
const double = x => x + x
console.log(Identity(35)) //=> 35
console.log(map(double, Identity(35))) // ERROR Should be Identity(70)
console.log(setter(double, 35)) // ERROR Should be: 70
TypeError: Type-variable constraint violation
map :: Functor f => (a -> b) -> f a -> f b
^ ^
1 2
1) 35 :: Number, FiniteNumber, NonZeroFiniteNumber, Integer,
NonNegativeInteger, ValidNumber
2) () => x :: Function, (c -> d)
f => Identity(f(x)) :: Function, (c -> d)
Since there is no type of which all the above values are members, the
type-variable constraint has been violated.
Однако функтор Const работает немного лучше (на карте не вызывается f)
const Const = function(x) {
const self = getInstance(this, Const)
self[map] = _ => Const(x)
self[extract] = () => x
return Object.freeze(self)
}
const getter = (f, x) => (pipe([
Const,
map(f),
extractFrom
])(x))
console.log(getter(double, 35)) //=> 35
Далее все "логически правильно", что доказано удалением проверки типа
const {create, env} = require('sanctuary');
const {map, pipe, curry} = create({checkTypes: false, env: env});
или заменив святилище рамдой.Так что это похоже на проблему согласованности типов с функцией Identity Map.
Вопрос в том, как мне заставить все эти партии играть вместе в типичной счастливой манере.