Новый тип Haskell с круглыми скобками
Я пытаюсь понять объяснение в Монады, сделанные трудными, и мне сложно определить следующее определение newtype:
newtype (FComp g f) x = FComp { unCompose :: g (f x) }
instance (Functor b c f, Functor a b g) => Functor a c (FComp g f) where
fmap f (FComp xs) = FComp $ fmap (fmap f) xs
Я нигде не видел объяснения того, что означает newtype с выражением в круглых скобках вместо объявления типа. Поэтому я не могу понять, что означает определение функции fmap. Я также не понимаю, почему атрибут доступа unCompose определен, но никогда не используется. Я чувствую, что мне не хватает базовой семантики нового типа.
Ответы
Ответ 1
Вы можете написать это:
newtype (FComp g f) x = FComp { unCompose :: g (f x) }
так:
newtype FComp g f x = FComp (g (f x))
unCompose (FComp it) = it
Это потому, что приложение типа имеет те же синтаксические свойства, что и обычные приложения, то есть:
a b c = (a b) c
выполняется для значений a, b, c и для типов a, b, c.
Ответ 2
Небольшой тест:
newtype (FComp g f) x = FComp { unCompose :: g (f x) }
newtype FComp2 g f x = FComp2 { unCompose2 :: g (f x) }
*Main> :i FComp
newtype FComp g f x = FComp {unCompose :: g (f x)}
-- Defined at Test.hs:34:10
*Main> :i FComp2
newtype FComp2 g f x = FComp2 {unCompose2 :: g (f x)}
-- Defined at Test.hs:35:9
Итак, скобки действительно ничего не меняют. Это точно так же, как без них.
Что касается uncompose
, это просто имя для разворачивания newtype
без явного указания конструктора данных. В опубликованном фрагменте они используют сопоставление шаблонов, но не хотят экспортировать детали реализации, поэтому uncompose
предоставляется для использования содержимого FComp
. Это то же самое, что и в определениях data
, только то, что newtype
хочет ровно одно поле вместо 0..n.