newtype ReaderT r m a :: * -> (* -> *) -> * -> *
Я не могу понять, как понять выше выражения, особенно * -> (* -> *) -> * -> *
Считыватель Трансформатор Монада
newtype ReaderT r m a :: * -> (* -> *) -> * -> *
Я не могу понять, как понять выше выражения, особенно * -> (* -> *) -> * -> *
Считыватель Трансформатор Монада
Это должно быть на самом деле
ReaderT :: * -> (* -> *) -> * -> *
Грубо говоря, выше тип является типом функции, принимает аргумент типа *
, другой тип * -> *
, другой тип *
и производит результат типа *
. Тип *
является «типом всех типов». Например. Int :: *
, Char :: *
и т.д.
Чтобы избежать путаницы, *
не действительно называется «тип», но «своего рода», чтобы отразить, что он работает на более высоком уровне. Например, 'a'
имеет тип Char
, а Char
имеет вид *
.
Наконец, вид * -> *
является своего рода конструкторами одинарных типа, такие как Maybe
, []
, IO
, (,) Char
, Either Bool
и т.д. Все это принять аргумент типа и возвращать тип. Вид * -> *
также является видом любого функтора, аппликативного или монада.
Так что, если у нас есть тип r
, конструктор типа m
(обычно, монада), и тип a
, мы имеем:
r :: *
m :: (* -> *)
a :: *
ReaderT :: * -> (* -> *) -> * -> *
ReaderT r :: (* -> *) -> * -> *
ReaderT r m :: * -> *
ReaderT r m a :: *
Следовательно, когда пройдены все три аргумента, результат ReaderT r m a
является типом.
why '(* -> *)' является монадой? – Gilgamesz
@Gilgamesz '* -> *' не является монадой, но если у вас есть монада 'm', то' m' должен иметь вид '* -> *'. Например. 'm = Maybe', или' m = IO' – chi
'(,)' is '* -> * -> *' no? Я думал, что вы не можете думать о '* -> *' как '*'. – jakubdaniel
Ваш вопрос и пример не так понятны –
это вид-подпись - символ '*' обозначает тип, поэтому он сообщает вам, что 'r' - это тип,' m' - это тип-конструктор (например, '' Может быть, 'или' IO' - вы даете им тип, и они возвращают один), а 'a' является типом - результат (который является« ReaderT rma') снова является типом - он просто поможет вам понять вовлеченные части ;) – Carsten