繁体   English   中英

使用rank-2类型和函数组合键入错误

[英]Type error with rank-2 types and function composition

这里有一些pragma和一些导入:

{-# LANGUAGE ScopedTypeVariables #-}

import Control.Monad.ST
import Data.Array.ST
import Data.Array

现在这是我的问题。 以下代码类型检查:

foo :: forall a. a -> [a]
foo x = elems $ runSTArray $ do
    newListArray (1,10) (replicate 10 x) :: ST s (STArray s Int a)

但是,当我用组合替换$时:

foo :: forall a. a -> [a]
foo x = elems . runSTArray $ do
    newListArray (1,10) (replicate 10 x) :: ST s (STArray s Int a)

我收到此错误:

Couldn't match expected type `forall s. ST s (STArray s i0 e0)'
            with actual type `ST s0 (STArray s0 Int a)'
In the expression:
    newListArray (1, 10) (replicate 10 x) :: ST s (STArray s Int a)
In the second argument of `($)', namely
  `do { newListArray (1, 10) (replicate 10 x) ::
          ST s (STArray s Int a) }'
In the expression:
      elems . runSTArray
  $ do { newListArray (1, 10) (replicate 10 x) ::
           ST s (STArray s Int a) }

令人担忧的是,如果我给函数组合赋予自己的名字,那么它再次进行类型检查:

elemSTArray = elems . runSTArray

foo :: forall a. a -> [a]
foo x = elemSTArray $ do
    newListArray (1,10) (replicate 10 x) :: ST s (STArray s Int a)

我不确定这里发生了什么。 我希望第二段代码可以很好地进行类型检查。 如果我给这个组合函数赋予它自己的名字,我不明白为什么它会再次出现问题。

这是我从GHC 6.2升级到7时破坏的一些代码的简化版本,我试图理解为什么会发生这种情况。 谢谢你的帮助!

正如您在帖子的标题中暗示的那样,问题与runSTArray的多态类型为2级有关。

runSTArray :: Ix i => (forall s. ST s (STArray s i e)) -> Array i e

elems :: Ix i => Array i e -> [e]

($) :: (a -> b) -> a -> b

编写runSTArray $ ...意味着($)类型模式中的类型变量a需要使用多态类型而不是单态类型进行实例化。 这需要所谓的不可预测的多态性。 在Dimitrios Vytiniotis,Stephanie Weirich和Simon Peyton Jones的ICFP 2008论文中解释了GHC如何实现不可预测的多态性: FPH:Haskell的一流多态性 最重要的是,尽管FPH通常会为您提供您期望的行为,但有时候不会像您在问题中描述的简单转换那样保留可打字性:请参阅上述文章的第6.2节。

斯特凡打我的答案-棘手的一点是,它不是$ VS . elemsrunSTArray之间发生了问题 - 它是跟随runSTArray$ 因为something $ rankNthing是如此常见,所以有一个聪明的位(我忘记了细节)试图让你做到这一点作为一个角落案例。 但不知何故使用早期的组合可以防止这种情况发生 问题的位置通过以下事实证明:

foo x = (elems . runSTArray) (
    (newListArray (1,10) (replicate 10 x) :: ST s (STArray s Int String)))

我不确定这本身就是一个bug,但它确实是一个值得创建故障的意外行为,因为可能仍有更好的算法来捕获像你提供的那样的案例。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM