类型同义词的部分应用
Partial application of 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)
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
但这与 The type synonym 'MkT' should have 2 arguments, but has been given 1
相呼应。我可以将 MapReturnType
专门化为 MkT (CollectArgTypes t)
,但我更喜欢它的现状。
由于 -XLiberalTypeSynonyms
似乎没有交付(为什么?),我有什么选择可以让 BuryT
工作?
LiberalTypeSynonyms
通过内联所有“显而易见的”类型定义来工作。为了让你的例子工作,它必须
- 先把
MapReturnType (MkT (CollectArgTypes t)) t
当作一些MapReturnType ㄊ t
- 使用定义
MapReturnType f r = f r
将其内联到 ㄊ t
- 在这一点上,再次调用
ㄊ
将得到 MkT (CollectArgTypes t) t
,这是一个非常好的完全应用的同义词,因此没有问题。
但是第 2 步是不可能的,因为 MapReturnType
而不是 只是一个同义词。要使用 MapReturnType f r = f r
,编译器首先必须确保 r
不是函数类型,但它真的不知道这一点——毕竟它是一个完全自由的参数。
因此,编译器实际需要做的是,将 MapReturnType
的解析以及 BuryT
的解析延迟到具体的使用站点。现在,这可能非常有用,但它会打开一大堆蠕虫。也就是说,在你的程序类型中的任何地方都可以很容易地交织图灵完备程序。我认为这不值得。
我在以下示例中遇到了不饱和类型同义词的问题:
{-# 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
但这与 The type synonym 'MkT' should have 2 arguments, but has been given 1
相呼应。我可以将 MapReturnType
专门化为 MkT (CollectArgTypes t)
,但我更喜欢它的现状。
由于 -XLiberalTypeSynonyms
似乎没有交付(为什么?),我有什么选择可以让 BuryT
工作?
LiberalTypeSynonyms
通过内联所有“显而易见的”类型定义来工作。为了让你的例子工作,它必须
- 先把
MapReturnType (MkT (CollectArgTypes t)) t
当作一些MapReturnType ㄊ t
- 使用定义
MapReturnType f r = f r
将其内联到 - 在这一点上,再次调用
ㄊ
将得到MkT (CollectArgTypes t) t
,这是一个非常好的完全应用的同义词,因此没有问题。
ㄊ t
但是第 2 步是不可能的,因为 MapReturnType
而不是 只是一个同义词。要使用 MapReturnType f r = f r
,编译器首先必须确保 r
不是函数类型,但它真的不知道这一点——毕竟它是一个完全自由的参数。
因此,编译器实际需要做的是,将 MapReturnType
的解析以及 BuryT
的解析延迟到具体的使用站点。现在,这可能非常有用,但它会打开一大堆蠕虫。也就是说,在你的程序类型中的任何地方都可以很容易地交织图灵完备程序。我认为这不值得。