外部绑定类型声明没有ScopedTypeVariables [英] Outer bound type declarations without ScopedTypeVariables

查看:65
本文介绍了外部绑定类型声明没有ScopedTypeVariables的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  { - #LANGUAGE ScopedTypeVariables# - } 
模块Control.Retry其中

导入前导隐藏(catch)
导入Control.Exception
导入Control.Concurrent

重试[]动作=动作
重试(i:is)action = catch action processError
where
processError(e :: IOException)= threadDelay i>>重试是行动

出于好奇,我想知道如何在不使用<$ c的情况下重新实现$ c> ScopedTypeVariables 编译指示,或者我是否可以,以及 processError 的推断类型声明实际上是什么,因为指定 processError :: IOException - >> IO a 使它不可编译。

解决方案

如果你想避免 ScopedTypeVariables ,你可以在大部分时间使用 asTypeOf

  retrying [] action = action 
retrying(i:is)action = catch action processError
where
processError e = snd(e`asTypeOf`(undefined :: IOException), threadDelay i>> retrying is action)

undefined :: IOException 是一个表达式类型的签名,这是标准允许的。 asTypeOf 要求例外 e IOException



尽管如此,我还是倾向于使用 ScopedTypeVariables

With

  retrying :: [Int]  - > IO a  - > IO a 

类型的 processError 被推断作为

  processError :: IOException  - > IO a 

a 这里是与重试签名中的变量相同。但是,在没有 ScopedTypeVariables 扩展名的情况下,该类型可以在Haskell中指定,因为在书写签名中的类型变量默认是全局量化的。


I have a following working definition:

{-# LANGUAGE ScopedTypeVariables #-}
module Control.Retry where

import Prelude hiding (catch)
import Control.Exception
import Control.Concurrent

retrying [] action = action 
retrying (i:is) action = catch action processError
  where 
    processError (e :: IOException) = threadDelay i >> retrying is action

Just out of curiosity I am wondering how I could reimplement this without utilizing the ScopedTypeVariables pragma, or whether I could at all, and what the inferred type declaration of processError actually is, because specifying processError :: IOException -> IO a makes it uncompilable.

解决方案

If you want to avoid ScopedTypeVariables, you can most of the time use asTypeOf.

retrying [] action = action 
retrying (i:is) action = catch action processError
  where 
    processError e = snd (e `asTypeOf` (undefined :: IOException), threadDelay i >> retrying is action)

The undefined :: IOException is an expression type signature, and that is allowed by the standard. The asTypeOf requires the exception e to be an IOException.

I would prefer ScopedTypeVariables here, though.

With

retrying :: [Int] -> IO a -> IO a

the type of processError is inferred as

processError :: IOException -> IO a

with the a here being the same type variable as in the signature of retrying. That type can, however, not be specified in Haskell without the ScopedTypeVariables extension, since type variables in written-down signatures are by default universally quantified.

这篇关于外部绑定类型声明没有ScopedTypeVariables的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆