ScopedTypeVariables无法与嵌套where子句一起使用? [英] ScopedTypeVariables fail to work with nested where-clauses?

查看:48
本文介绍了ScopedTypeVariables无法与嵌套where子句一起使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个非常人为的例子,但是无论如何……这种类型的检查:

It's a horribly contrived example, but anyway... this typechecks:

newtype Foo c = Foo { runFoo :: c -> Bool }
newtype Bar c = Bar { runBar :: Int -> c }

foo :: Eq c => Bar c -> (c -> [c]) -> Bar (Foo c)
foo bar f = Bar res
 where res n = Foo judge
        where judge c = (c`elem`) . f $ runBar bar n

工作

GHCi>让foo0 = foo(条形码)(\ n-> [n,n * 2])
GHCi>地图(runFoo $ runBar foo0 4)​​[1..10]
[False,False,False,True,False,False,False,True,False,False]

GHCi> let foo0 = foo (Bar id) (\n -> [n, n*2])
GHCi> map (runFoo $ runBar foo0 4) [1..10]
[False,False,False,True,False,False,False,True,False,False]

但是如果我将明显的类型签名添加到本地函数 judge

but if I add the obvious type signature to the local function judge,

foo :: Eq c => Bar c -> (c -> [c]) -> Bar (Foo c)
foo bar f = Bar res
 where res n = Foo judge
        where judge :: c -> Bool
              judge c = (c`elem`) . f $ runBar bar n

失败

Could not deduce (c ~ c2)
from the context (Eq c)
  bound by the type signature for
             foo :: Eq c => Bar c -> (c -> [c]) -> Bar (Foo c)

,依此类推.在Haskell 98中不足为奇,但我认为 ScopedTypeVariables 应该允许编写此类签名,但显然不允许这样做.是否有特定的原因,是否有意使它不适用于嵌套的 where ,并且如果出现类似的实词问题,有什么解决方法?

and so on. Hardly surprising in Haskell 98, but I'd think ScopedTypeVariables should allow to write such signatures, but apparently it doesn't. Is there a specific reason for this, is it intentional that it doesn't work with nested wheres, and what workarounds are there if this turns up in a comparable real-word problem?

推荐答案

显然,您忘记了将类型变量 c 引入显式的 forall 范围内,

Apparently you forgot to bring the type variable c into scope with an explicit forall,

{-# LANGUAGE ScopedTypeVariables #-}
module Foobar where

newtype Foo c = Foo { runFoo :: c -> Bool }
newtype Bar c = Bar { runBar :: Int -> c }

foo :: forall c. Eq c => Bar c -> (c -> [c]) -> Bar (Foo c)
foo bar f = Bar res
 where res n = Foo judge
        where judge :: c -> Bool
              judge c = (c`elem`) . f $ runBar bar n

编译良好.

ScopedTypeVariables 本身不会将签名中的类型变量带入范围,仅将具有显式 forall 的那些变量带入范围.

ScopedTypeVariables by itself doesn't bring the type variables from the signature into scope, only those with an explicit forall are brought into scope.

这篇关于ScopedTypeVariables无法与嵌套where子句一起使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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