повторное использование псевдонимов типа в псевдонимах типа - PullRequest
1 голос
/ 10 апреля 2019

Поэтому я был очень впечатлен на днях, когда увидел ...

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...