数据声明中的推断类型
Inferred type in data declaration
现在有好几次我 运行 在尝试将推断类型的单子操作包含到现有的显式类型数据声明中时遇到麻烦:
data Thing = Thing { x :: Int }
t = Thing { x = 42 }
-- action :: m (Maybe (n ())), for some horrendous,
-- deeply parameterized monad transformer stacks m, n
action = return Nothing
data Thing' = Thing' { x :: Int, y :: ? }
t' = Thing' { x = 42, y = action }
我不想写下新字段的完整类型是什么——事实上,我尝试过但失败了。在大多数其他时间,我可以让程序的其余部分告知表达式的类型,我希望我可以在这里这样做。
我猜测,当我在用户定义的数据结构中包含此类推断类型的数据时,我必须放弃很多编译器类型推断支持。那是准确的,还是我遗漏了什么?
I’m surmising that I must give up a lot of compiler type inference support when I include data of such an inferred type in a user-defined data structure. Is that accurate, or am I missing something?
正确,类型推断不会从使用位置到类型定义。
您可以将 Thing'
的参数设置为 y
的类型:
data Thing' yType = Thing' { x :: Int, y :: yType }
然后编译器会根据其用法推断出 t'
的类型。
这会起作用
{-# LANGUAGE RankNTypes, ExistentialQuantification #-}
data Thing' = forall a m. Monad m => Thing' { x:: Int, y :: m a }
但你是对的,启用这些语言特性在某种意义上会使编译器变弱,因为类型推断不再强大到足以计算出某些东西的类型,你将不得不添加一个类型归属,所以类型检查器可以填写。或者至少我是这样理解的。
现在有好几次我 运行 在尝试将推断类型的单子操作包含到现有的显式类型数据声明中时遇到麻烦:
data Thing = Thing { x :: Int }
t = Thing { x = 42 }
-- action :: m (Maybe (n ())), for some horrendous,
-- deeply parameterized monad transformer stacks m, n
action = return Nothing
data Thing' = Thing' { x :: Int, y :: ? }
t' = Thing' { x = 42, y = action }
我不想写下新字段的完整类型是什么——事实上,我尝试过但失败了。在大多数其他时间,我可以让程序的其余部分告知表达式的类型,我希望我可以在这里这样做。
我猜测,当我在用户定义的数据结构中包含此类推断类型的数据时,我必须放弃很多编译器类型推断支持。那是准确的,还是我遗漏了什么?
I’m surmising that I must give up a lot of compiler type inference support when I include data of such an inferred type in a user-defined data structure. Is that accurate, or am I missing something?
正确,类型推断不会从使用位置到类型定义。
您可以将 Thing'
的参数设置为 y
的类型:
data Thing' yType = Thing' { x :: Int, y :: yType }
然后编译器会根据其用法推断出 t'
的类型。
这会起作用
{-# LANGUAGE RankNTypes, ExistentialQuantification #-}
data Thing' = forall a m. Monad m => Thing' { x:: Int, y :: m a }
但你是对的,启用这些语言特性在某种意义上会使编译器变弱,因为类型推断不再强大到足以计算出某些东西的类型,你将不得不添加一个类型归属,所以类型检查器可以填写。或者至少我是这样理解的。