Чтобы отступить от особенностей используемых вами библиотек, вот как работает type
:
Я могу объявить синоним типа
type ListOfInts = [Int]
Я знаю, что могу использовать ListOfInts везде, где я бы использовал [Int]:
f :: ListOfInts -> Int
f xs = sum xs
g :: [Int] -> Int
g xs = product xs
list1 :: [Int]
list1 = [1,2,3]
list2 :: ListOfInts
list2 = [4,5,6]
f list1
> 6
f list2
> 15
g list1
> 6
g list2
> 120
И теперь я могу использовать f
и g
как для list1, так и для list2, несмотря на то, что они объявлены с «разными» типами. Тип просто объявляет синоним для типа, а не новый тип (который будет использовать ключевое слово newtype
).
Таким образом, вы можете использовать CtrlV
так же, как вы использовали бы Ctrlv' Response
, который вы можете использовать так же, как вы использовали бы RouteT SiteMap App Response
, который вы можете использовать так же, как вы использовали бы RouteT SiteMap (ServerPartT IO) Response
, потому что Ctrlv
- это RouteT SiteMap (ServerPartT IO) Response
.