如何使用显式类型应用进行专业化?

18

使用 GHC 8.0,我可以编写一个模糊的函数,它在其类型签名的主要部分中没有提到某些类型,然后使用显式类型应用调用它:

{-# LANGUAGE ScopedTypeVariables, RankNTypes,
             AllowAmbiguousTypes, TypeApplications, TypeFamilies #-}

showRead :: forall t . (Read t, Show t) => String -> String
showRead x = show (read x :: t)

showReadInt = showRead @Int

我想使用一个SPECIALIZE指令来强制特化showRead函数的Int参数(在我的实际代码中,调用点在另一个模块中)。然而,正常的SPECIALIZE语法是基于编写类型签名的主要部分,例如:
{-# SPECIALIZE showRead :: String -> String #-}

在这种情况下,我无法指定t应该是什么,这很容易导致出现歧义的错误。

我尝试使用等式约束:

{-# SPECIALISE showRead :: forall t . (Read t, Show t, t ~ Int) => String -> String #-}

但这只是给出了错误信息:

Could not deduce (Read t0) a SPECIALISE pragma for ‘showRead’
  from the context: (Read t, Show t, t ~ Int)
    bound by the type signature for:
               showRead :: (Read t, Show t, t ~ Int) => String -> String
    at foo.hs:4:1-76
  The type variable ‘t0’ is ambiguous

有没有什么方法可以做到这一点?当然,我可以使用代理,但不使用这种新的方式似乎是一种浪费。


1
我不知道答案,但我知道像这样使用模糊函数的能力是非常新的,多亏了 GHC8 的新类型应用语法。因此,如果答案是“目前还不支持”,我也不会感到惊讶。 - Benjamin Hodgson
1
@dfeuer:我认为问题在于现有的/syntax/不适合指定它。代理和模糊类型之间唯一的真正区别在于类型参数是显式还是隐式。 - GS - Apologise to Monica
听起来很有道理,但可能比仅为模糊类型暴露现有的类型特化功能要更费力。如果有一个可以同时表达两者的好语法,也许可以使用它,但是值特化最初未被实现。 - GS - Apologise to Monica
@GaneshSittampalam 确实。我在思考类似 RULES showRead @Int = showReadInt 这样的东西。 - chi
也许只需要在它上面加一个INLINE? - jberryman
显示剩余4条评论
1个回答

1

这在 GHC 8.0 中不被支持,但现在成为一个提案,将在未来的 GHC 中得到支持。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接