【问题标题】:Type error when using function composition with RankNTypes [duplicate]将函数组合与 RankNTypes 一起使用时出现类型错误 [重复]
【发布时间】:2015-10-23 11:37:53
【问题描述】:

我对以下程序感到困惑。

{-# LANGUAGE RankNTypes #-}
newtype A a = A ( forall f. Applicative f => f a )

good :: a -> A a
good x = A $ pure $ x

bad  :: a -> A a
bad  x = A . pure $ x

尝试编译时,我收到此错误消息,抱怨bad

Couldn't match type `f0 a'
               with `forall (f :: * -> *). Applicative f => f a'
Expected type: f0 a -> A a
  Actual type: (forall (f :: * -> *). Applicative f => f a) -> A a
Relevant bindings include
  x :: a (bound at huh.hs:8:6)
  bad :: a -> A a (bound at huh.hs:8:1)
In the first argument of `(.)', namely `A'
In the expression: A . pure

为什么函数 good 会进行类型检查,而 ghc 拒绝接受函数 bad?我该怎么做才能使后一个版本正常工作?据我所知,这两个例子应该是等价的。

【问题讨论】:

  • 简而言之:Haskell 的类型系统是可预测的,这意味着它不会实例化具有多态类型的类型变量(带有foralls 的类型变量)。为了让bad 进行类型检查,类型检查器需要用forall (f :: * -> *). Applicative f => f a 实例化一些类型变量。但是,即使您打开-XImpredictiveTypes,您仍然需要在pure 上添加类型注释。
  • @user2407038,predicAtive 和 impredicAtive。
  • 永远不要使用ImpredicativeTypes,除非有一天它真的被修复了。

标签: haskell existential-type


【解决方案1】:

正如在几个 cmets 中所解释的,问题在于类型系统无法预测这是一个有效的类型,即使它是。在this answer 中有一个提示,您可以明确指定. 的类型来解决问题。

此代码 sn-p 有效:

-- Type specialized composition
(.!) :: ((forall f. Applicative f => f b) -> c) ->
        (a -> (forall f. Applicative f => f b)) -> a -> c
(.!) f g x = f(g x)

-- Use the new version of composition
notBad  :: a -> A a
notBad  x = A .! pure $ x

【讨论】:

    猜你喜欢
    • 2021-11-21
    • 1970-01-01
    • 2016-08-28
    • 1970-01-01
    • 2019-09-18
    • 2018-02-25
    • 2017-08-09
    • 2020-10-09
    • 1970-01-01
    相关资源
    最近更新 更多