TypeOperators
つまり、型の定義内で演算子を使える
つまり、演算子な型コンストラクタを定義できる
defaultでは (->)
が型演算子として定義されている
ghci:t id
> id :: a -> a -- 中置演算子として表示されている
:t id :: (->) a a
> id :: (->) a a :: a -> a -- 前置としても機能する
例
ghci> data a + b = Add a b
> :t Add
Add :: a -> b -> a + b
> :k (+)
(+) :: * -> * -> *
> :k (+) Int -- 部分適用も同様
(+) Int :: * -> *
hs{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeOperators #-}
data HList xs where
HNil :: HList '[]
(:::) :: a -> HList as -> HList (a ': as)
hstype UserAPI = "users" :> "list" :> Get '[JSON] [User]
Getを受け付ける /users/list
というendpointを型レベルで定義している
右結合になる
TypeOperator固有の話でもない

kind一般の話
* -> * -> *
は、 * -> (* -> *)
と同じ
参考
型アノテーションの能力も上がっているのか

prefixのアノテーションは元からできるが、infixのは拡張によってできるようになる