Haskell 类型同义词的部分应用

Haskell 类型同义词的部分应用,haskell,ghc,type-families,partial-application,type-synonyms,Haskell,Ghc,Type Families,Partial Application,Type Synonyms,在以下示例中,我在使用非饱和类型同义词时遇到问题: {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE LiberalTypeSynonyms #-} module TypeFamilyHackery where data T k v a = T type family CollectArgTypes arr where CollectArgTypes (a -> b) = (a, CollectArgTypes b) CollectArgT

在以下示例中,我在使用非饱和类型同义词时遇到问题:

{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE LiberalTypeSynonyms #-}

module TypeFamilyHackery where

data T k v a = T

type family CollectArgTypes arr where
  CollectArgTypes (a -> b) = (a, CollectArgTypes b)
  CollectArgTypes _ = ()

type family MapReturnType f t where
  MapReturnType f (a -> b) = a -> MapReturnType f b
  MapReturnType f r = f r

type MkT k v = T k v v

-- | Goal:
-- @
--   BuryT Int = T () Int Int
--   BuryT (Bool -> Int) = Bool -> T (Bool, ()) Int Int
--   BuryT (a -> b -> c) = a -> b -> T (a,(b,())) c c
-- @
type BuryT t = MapReturnType (MkT (CollectArgTypes t)) t
但这会导致类型同义词“MkT”应具有2个参数,但已给出1个参数。我可以专门为MkT CollectArgtype指定MapReturnType,但我更喜欢它的样子

既然-XLiberalTypeSynonyms似乎无法解释原因,那么我有什么办法让BuryT工作呢?

LiberalTypeSynonyms通过内联所有“明显的”类型定义来工作。为了让你的例子起作用,它必须

首先将MapReturnType MkT CollectArgTypes t视为某些MapReturnTypeㄊ T 将此内联到ㄊ t、 使用定义MapReturnType f r=f r 此时,调用ㄊ 再次给出MkT CollectArgTypes,这是一个非常好的完全应用的同义词,因此没有问题。 但是步骤2是不可能的,因为MapReturnType不仅仅是同义词。要使用MapReturnType f r=f r,编译器首先必须确保r不是函数类型,但它确实不知道这一点——毕竟它是一个完全自由的参数

因此,编译器实际上需要做的是,将mapreurntype的解析推迟到具体的使用站点,从而也将BuryT的解析推迟到具体的使用站点。现在,这可能非常有用,但它会打开一个相当多的蠕虫罐头。也就是说,在程序类型中的任何地方都可以很容易地将图灵完整程序交织在一起。我认为这不值得。

LiberalTypeSynonyms通过内联所有“明显的”类型定义来工作。为了让你的例子起作用,它必须

首先将MapReturnType MkT CollectArgTypes t视为某些MapReturnTypeㄊ T 将此内联到ㄊ t、 使用定义MapReturnType f r=f r 此时,调用ㄊ 再次给出MkT CollectArgTypes,这是一个非常好的完全应用的同义词,因此没有问题。 但是步骤2是不可能的,因为MapReturnType不仅仅是同义词。要使用MapReturnType f r=f r,编译器首先必须确保r不是函数类型,但它确实不知道这一点——毕竟它是一个完全自由的参数


因此,编译器实际上需要做的是,将mapreurntype的解析推迟到具体的使用站点,从而也将BuryT的解析推迟到具体的使用站点。现在,这可能非常有用,但它会打开一个相当多的蠕虫罐头。也就是说,在程序类型中的任何地方都可以很容易地将图灵完整程序交织在一起。我认为这不值得。

谢谢!所以我一直坚持把类型转换成MkT,不是吗?谢谢!所以我一直坚持把类型映射到MkT,不是吗?