在前奏中,有关ReaderT
的类型信息表示:
newtype ReaderT r (m :: k -> *) (a :: k)
= ReaderT {runReaderT :: r -> m a}
(m :: k -> *)
是什么意思? m
采用k
类型的参数,但m
是更高级的类型。
有关更高性感外观的信息也有线:
Prelude> :k ReaderT
ReaderT :: * -> (k -> *) -> k -> *
答案 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 }
右侧表示r
和m a
必须都是具体类型(种类*
)。从这里可以推断r
是*
种类,而m
只接受一个参数并生成一个具体类型(m
是something -> *
种类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;
)。所以,在这种情况下,泛化是没用的。