首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >避难所Js和定义逆变函数器

避难所Js和定义逆变函数器
EN

Stack Overflow用户
提问于 2018-06-09 20:30:43
回答 2查看 326关注 0票数 0

我正在从头开始尝试,学习Contravariants和更深入的Sanctuary知识。代码“可以工作”,但是我的类型并不完全正确。

下面是Contravariant

代码语言:javascript
运行
复制
const {contramap: contramapFl, extract } = require('fantasy-land');
const getInstance = (self, constructor) =>
    (self instanceof constructor) ?
        self :
        Object.create(constructor.prototype) ;
// Contra a ~> g: a -> ?
const Contra = function(g){
    const self = getInstance(this, Contra)

    // :: F a ~> b -> a -> F b [ b -> a -> ? ]
    self[contramapFl] = f => Contra( x => g(f(x)) )
    self[extract] = g
    self['@@type'] =  'fs-javascript/contra'

    return Object.freeze(self)
}
// UPDATE adding type to constructor
Contra['@@type'] =  'fs-javascript/contra'

我尝试将类型设置为正确的

代码语言:javascript
运行
复制
const $ = require('sanctuary-def');
const type = require('sanctuary-type-identifiers');
const Z = require('sanctuary-type-classes') ;

const isContra = x => type (x) === 'fs-javascript/contra'

const ContraType = $.UnaryType(
    'fs-javascript/contra',
    'http://example.com/fs-javascript#Contra',
    isContra,
    x => [x[extract]])($.Unknown)

然后我的测试

代码语言:javascript
运行
复制
const {create, env} = require('sanctuary');
const {contramap} = create({checkTypes: true, env: env.concat(ContraType) });

const isEven = Contra(x => x % 2 === 0) ;
console.log(Z.Contravariant.test(isEven)) // => true

const isLengthEvenContra = contramap(y => y.length, isEven)
const isStringLengthEven = isLengthEvenContra[extract]

console.log(isStringLengthEven("asw")) //=> ERROR

TypeError:类型变量约束违反Contra ::Contravariant f => (b -> a) -> f a -> f b^11)“fs-javascript/ =>”::String f => (x=>g(f(X) ::Function,(c -> d) x => x%2函数0 ::===,(c -> d)由于不存在上述所有值都是其成员的类型,因此违反了类型变量约束。

如果我禁用了类型检查,那么它就会按预期工作,所以从逻辑上讲,它看起来是正确拼接在一起的。我定义了我自己的contramap版本

代码语言:javascript
运行
复制
const def = $.create({ checkTypes: true, env: $.env.concat(ContraType) });

const contramap2 =
    def('contramap2', {}, [$.Unknown, ContraType, ContraType],
        (f, x) => {
            const z = x[contramapFl](f)
            return z
        }
    )

然后我重新运行测试:

代码语言:javascript
运行
复制
const isEven = Contra(x => x % 2 === 0) ;
console.log(Z.Contravariant.test(isEven)) // => true

const isLengthEvenContra = contramap2(y => y.length, isEven)
const isStringLengthEven = isLengthEvenContra[extract]

console.log(isStringLengthEven("asw")) //=> false

因此,尽管存在关于对比函数器是否是解决此问题的最佳方法(学习练习)的讨论,但问题是,当定义我自己的逆变量实现时,我如何在启用了类型检查的中使用避难所的对比映射函数。

通过添加代码进行更新后:

代码语言:javascript
运行
复制
Contra['@@type'] =  'fs-javascript/contra'

已将错误更改为:

TypeError:类型变量约束违反contramap ::Contravariant f => (b -> a) -> f a -> f b^1^1 1) 3 ::Number,FiniteNumber,NonZeroFiniteNumber,Integer,NonNegativeInteger,ValidNumber 2) x => x%2 === 0 ::Function,(c -> d)由于不存在上面所有值都是其成员的类型,已违反类型变量约束。

代码语言:javascript
运行
复制
// Contra (Integer -> Boolean)
const isEven = Contra(x => x % 2 === 0) ;
// String -> Integer
const strLength = y => y.length
// I Think: Contra (String -> (Integer -> Boolean))
const isLengthEvenContra = contramap(strLength, isEven)
// (String -> (Integer -> Boolean))
const isStringLengthEven = isLengthEvenContra[extract]

我对反变量函数器的理解是,它预先组合了其中的函数,函数是通过contramap传入的。因此,如果逆变量包含函数f,并且它是带有gcontramap,它将返回一个新的包装x = g(f(x))的逆变函数,我是否误解了这()

EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50774333

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档