所以那天我看到...给我留下了深刻的印象
type Foo<'a> =
abstract foo : Unit -> 'a
type IsFoo<'a,'b when 'a :> Foo<'b>> = 'a
(我知道这个例子有点愚蠢) 关键是可以在类型别名中捕获复杂的参数约束。...很好
然后我开始使用此功能,但是到了需要使用Bar的功能的地步
type Bar<'b> =
abstract bar : Unit -> 'b
所以我们有
type IsBar<'a,'b when 'a :> Bar<'b>> = 'a
但是后来我想要一个Foo,它返回了一个酒吧。...所以我可以去...。(我认为)
type IsFooThenBar<'a,'b,'c when 'a :> Foo<'b> and 'b :> Bar<'c>> =
IsFoo<'a,IsBar<'b,'c>>
但这只是我已经知道的东西的重述...我真的很想推断约束,即
type IsFooThenBar2<'a,'b,'c> = IsFoo<'a,IsBar<'b,'c>>
但这显然不起作用,因为编译器抱怨除非我有必要的约束,否则我无法断言IsFoo和IsBar ...
有什么主意吗?....我的代码中有很多泛型约束,而这些约束实际上不能很好地与类型声明配合使用。
根据一些反馈进行澄清,我如何才能使用一组类型别名并将它们组合成更复杂的别名,而不必简单地重新声明它们。我希望能够修改一种公理化的别名,并将其反映为派生的别名,而无需进行大量的输入。
因此,我可以写
let f (x : IsFoo<_,IsBar<_,string>>) =
x.foo().bar()
在简单的情况下还可以...但是请记住我有很多参数...
所以我真的想简化并编写...
let f2 (x : IsFooThenBar<_,_,string>) =
x.foo().bar()
如果我如上所述定义IsFooThenBar,我当然可以做到。...
即类型别名为我提供了我想要的机制,但是似乎没有简单的方法来构成类型别名,而又不用重新定义顶级别名中的所有约束。
在这种情况下还可以。...但是对于大量参数,它变得越来越繁琐。
所以... Haskell是一种可以完成这种事情的语言示例...
> class Foo a b | a -> b where
> foo :: a -> b
>
> class Bar a b | a -> b where
> bar :: a -> b
> class (Foo foo bar,Bar bar a) => FooThenBar foo bar a where
然后我可以使用FooThenBar作为简写,它表示存在将'foo映射到'bar并将'bar映射到我指定的任何类型的函数
(我不是Haskell专家,必须获得帮助才能创建这种大致等效的场景)
这是原始功能
> f :: (Bar bar b, Foo foo bar) => foo -> b
> f x = bar (foo x)
这将使用新的推断组成
> f' :: (FooThenBar foo bar b) => foo -> b
> f' x = bar (foo x)