提问人:A Question Asker 提问时间:9/22/2023 更新时间:9/26/2023 访问量:70
fp-ts 如何让 'HKT<F, T>' 类型统一为 'F<T>'
How does fp-ts get the `HKT<F, T>` type to unify to `F<T>`
问:
我已经阅读了HKT https://github.com/gcanti/fp-ts/blob/master/docs/guides/HKT.md 的解释,并开始阅读代码...我了解嵌入并能够使用它,但我不太确定它是如何工作的,即打字稿编译器。在我看来很神奇的部分是,当您使用 end 方法时,类型将是 ,而不是......我很好奇那座桥是怎么发生的F<T>
HKT<F,T>
答:
2赞
Souperman
9/26/2023
#1
剥离相关代码和 HKT 解决方法,只看 TypeScript,请考虑以下代码:fp-ts
type Shape<T> = T extends Array<any> ? 'array' : 'value';
interface IFoo<T> {
value: Shape<T>;
}
type test1 = IFoo<number>['value'];
// ^? "value"
type test2 = IFoo<number[]>['value'];
// ^? "array"
当 TypeScript 计算出接口中索引字段的类型时,它会尝试尽可能简化值。在此示例中,您可以看到它计算条件类型并返回文本类型值。Shape
回到 HKT 的方法,我们也有类似的东西。有一个接口,用于从开发人员选择的字符串指向泛型类型。TypeScript 不允许你传递泛型类型,但它会让你传递字符串文字,并允许你索引到带有这些文字的接口中。它还将尝试尽可能简化类型。fp-ts
URItoKind
Shape
对于像 这样的内容,URI 被选为键,类型被隐藏起来,以便可以在更高种类的函数中查找它,并且当您有一个具体的实例时,类型检查器能够再次解析,拉走层。Functor<T>
'Functor'
URIToKind
Functor<T>
这是我自己对标识示例的注释,以说明正在发生的事情。
// Functor1 is going to pull values out of URIToKind
import { Functor1 } from 'fp-ts/Functor'
// Pick a name for the Identity type in the map.
export const URI = 'Identity'
// Make that chosen name available outside the module
export type URI = typeof URI
declare module 'fp-ts/HKT' {
// Set up a mapping from the literal string we chose to the actual
// * -> * Identity generic type
interface URItoKind<A> {
readonly Identity: Identity<A>
}
}
// Make Identity available outside the module (and actually define behavior)
export type Identity<A> = A
// Functor instance
// Functor1<URI> is doing a lot of work here. URI is the 'Identity' literal
// we chose, and `Functor1` is looking into the `URIToKind` map, indexing
// it with 'Identity' to get out the `Identity<A>` type which TS will then
// see it cannot refine further because it doesn't know `A` yet. It ends
// up with <A>(ma: Identity<A>, (a: A) => A) => A
export const Functor: Functor1<URI> = {
URI,
map: (ma, f) => f(ma)
}
评论