什么是k - > * 意思?

时间:2017-09-27 07:52:59

标签: haskell

在前奏中,有关ReaderT的类型信息表示:

newtype ReaderT r (m :: k -> *) (a :: k)
  = ReaderT {runReaderT :: r -> m a}

(m :: k -> *)是什么意思? m采用k类型的参数,但m是更高级的类型。

有关更高性感外观的信息也有线:

Prelude> :k ReaderT
ReaderT :: * -> (k -> *) -> k -> * 

1 个答案:

答案 0 :(得分:0)

片段(m :: k -> *)表示m k -> *的类型变量。反过来,这意味着m是一种更高级的类型,它采用一种类型(未指定种类k)并生成一种具体类型(即,亲切*)。

你在这里看到的只是GHC试图推断一种类型的最一般可能类型(与推断函数最常用的类型的方式相同)。

以下是推断此类推断的原因:ReaderT包中模块Control.Monad.Trans.Reader中给出的transformers的实际定义是:

newtype ReaderT r m a = ReaderT { runReaderT :: r -> m a }

右侧表示rm a必须都是具体类型(种类*)。从这里可以推断r*种类,而m只接受一个参数并生成一个具体类型(msomething -> *种类a }})。由于此定义没有对k的类型进行约束,因此GHC决定它可以具有任意类型m,这意味着k -> *的类型为k任意> :i ReaderT ... newtype ReaderT r (m :: k -> *) (a :: k) = ReaderT {runReaderT :: r -> m a} ...

这解释了两个:

> :k ReaderT
ReaderT ::    * -> (k -> *) -> k -> *
-- kinds of:  r        m       a    `-- (ReaderT r m a)

* -> *

现在,仅仅因为GHC推断这种一般类型并不表示它有任何用途或目的。由于所有monad都是ReaderT种类,因此创建a而不使用*m的唯一方法是使用它来“转换”实际上不是monad的Control.Monad.Reader,然后您将无法使用Monad m中使用product = Product.objects.get(pk=validated_data.pop('sku')) 约束的任何函数(几乎所有这些函数都是from .models import Product, Family, Location, Transaction from rest_framework import serializers class LocationSerializer(serializers.ModelSerializer): class Meta: model = Location fields = ('reference', 'title', 'description') class FamilySerializer(serializers.ModelSerializer): class Meta: model = Family fields = ('reference', 'title', 'description', 'unit', 'minQuantity') class ProductSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = Product fields = ('sku', 'barcode', 'title', 'description', 'location', 'family') depth = 1 class TransactionSerializer(serializers.ModelSerializer): product = ProductSerializer() class Meta: model = Transaction fields = ('sku', 'barcode', 'product') def create(self, validated_data): product = Product.objects.get(pk=validated_data.pop('sku')) instance = Transaction.objects.create(**validated_data) return instance def to_representation(self, instance): representation = super(TransactionSerializer, self).to_representatio n(instance) return representation; )。所以,在这种情况下,泛化是没用的。