Поэтому я был очень впечатлен на днях, когда увидел ...
type Foo<'a> =
abstract foo : Unit -> 'a
type IsFoo<'a,'b when 'a :> Foo<'b>> = 'a
(я знаю, что этот пример немного ненормальный), суть в том, что сложные параметрические ограничения могут быть захвачены в псевдониме типа.... nice
Затем я начал использовать это немного, но дошел до того, что у меня есть функция, которая требует 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 в «бар и бар», чтобы whateveЯ указываю тип r
(я не эксперт по 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)