2016-09-30 4 views
3

В Foldable documentaion, я вижу следующий пример:Роль звездочек (виды, *) в этом откидном случае

(Foldable f, Foldable g) => Foldable (Compose * * f g) 

Если я смотрю на определении Compose, я вижу, он объявлен как

newtype Compose f g a = Compose f (g a) 

, который имеет вид (* -> *) -> (* -> *) -> * -> *, справа? (что, как я полагаю, предполагается). Теперь, насколько я могу видеть, я предполагаю, что это было бы правильно написать:

(Foldable f, Foldable g) => Foldable (Compose f g) 

С Compose f g также имеет вид * -> *. Однако, я думаю, что есть два идентификатора kind. Но в чем причина?

+0

Я думаю, что это проблема с генерацией документации; дополнительные '*' отображаются в документации для экземпляров 'Compose',' Product' и 'Sum', но не в самом источнике. – chepner

ответ

2

Технически вид Compose является более общим, если вы включите PolyKinds:

newtype Compose (f :: k -> *) (g :: k' -> k) (a :: k') = Compose (f (g a)) 

Этот тип выведенный с PolyKinds и требует, чтобы написать (и это определено как таковое в library - обратите внимание, что PolyKinds включен в модуле).

Технически это Compose принимает два рода параметры, которые неявно. Это означает, что вы обычно не указываете их, и вы их обычно не видите. Тем не менее, это особенность Haddocks, что они показывают параметры вида. Но если вам интересно, вы можете видеть то же самое в GHCi, например,

>:set -fprint-explicit-kinds 
>import Data.Functor.Compose 
>:i Compose 
type role Compose nominal nominal representational nominal nominal 
newtype Compose k k1 (f :: k -> *) (g :: k1 -> k) (a :: k1) 
    = Compose {getCompose :: f (g a)} 
     -- Defined in `Data.Functor.Compose' 
.... 
instance [safe] (Foldable f, Foldable g) => 
       Foldable (Compose * * f g) 

Обратите внимание, что Compose дается два рода аргументы - * и * - потому что f и g должна быть доброй * -> * из-за Functor ограничений.

+0

Спасибо. Но нужно ли использовать PolyKinds? Я думал, что компилятор достаточно умен, чтобы понять это. –

+0

Рисунок, что? Регулярный Haskell не допускает добрых переменных - такая сигнатура типа даже не будет действительной. GHC по умолчанию соответствует Haskell 2010, поэтому он даже не позволит вам написать объявление типа как указано - он сказал бы вам включить «PolyKinds». – user2407038

 Смежные вопросы

  • Нет связанных вопросов^_^