简体   繁体   English

使用Data.Vector的“推断类型不明确”错误

[英]“Inferred type is ambiguous” error using Data.Vector

The following code fails to compile, with the error message given below. 以下代码无法编译,并显示以下错误消息。 f should simply be a state monad which when run creates a vector of length one with a single int "42". f应该只是一个状态monad,在运行时它会创建一个长度为1且具有单个int“ 42”的向量。 I suspect some ambiguity is happening between run and unstream much like show . read 我怀疑在rununstream之间会发生一些模棱两可的情况,就像show . read一样show . read show . read , but I can't figure out how to resolve it: show . read ,但我不知道如何解决它:

{-# LANGUAGE NoMonomorphismRestriction #-}

import Data.Vector.Generic.New (run, unstream)
import Data.Vector.Fusion.Stream (singleton)

f = run . unstream . singleton $ (42 :: Int)

main = return ()

Error: 错误:

main.hs:6:1:

Could not deduce (Data.Vector.Generic.Base.Vector v0 Int)
  arising from the ambiguity check for `f'
from the context (Data.Vector.Generic.Base.Vector v Int)
  bound by the inferred type for `f':
             Data.Vector.Generic.Base.Vector v Int =>
             GHC.ST.ST s (Data.Vector.Generic.Base.Mutable v s Int)
  at sort.hs:6:1-44
Possible fix:
  add an instance declaration for
  (Data.Vector.Generic.Base.Vector v0 Int)
When checking that `f'
  has the inferred type `forall (v :: * -> *) s.
                         Data.Vector.Generic.Base.Vector v Int =>
                         GHC.ST.ST s (Data.Vector.Generic.Base.Mutable v s Int)'
Probable cause: the inferred type is ambiguous

main.hs:6:1:

Could not deduce (Data.Vector.Generic.Base.Mutable v0
                  ~ Data.Vector.Generic.Base.Mutable v)
from the context (Data.Vector.Generic.Base.Vector v Int)
  bound by the inferred type for `f':
             Data.Vector.Generic.Base.Vector v Int =>
             GHC.ST.ST s (Data.Vector.Generic.Base.Mutable v s Int)
  at sort.hs:6:1-44
NB: `Data.Vector.Generic.Base.Mutable' is a type function, and may not be injective
Expected type: Data.Vector.Generic.Base.Mutable v s Int
  Actual type: Data.Vector.Generic.Base.Mutable v0 s Int
Expected type: GHC.ST.ST
                 s (Data.Vector.Generic.Base.Mutable v s Int)
  Actual type: GHC.ST.ST
                 s (Data.Vector.Generic.Base.Mutable v0 s Int)
When checking that `f'
  has the inferred type `forall (v1 :: * -> *) s1.
                         Data.Vector.Generic.Base.Vector v1 Int =>
                         GHC.ST.ST s1 (Data.Vector.Generic.Base.Mutable v1 s1 Int)'
Probable cause: the inferred type is ambiguous

You can generally resolve ambiguities like these by attaching a type annotation. 通常,您可以通过附加类型注释来解决此类歧义。 In this case, the question is, "Which instance of Vector va should I use when unstream creates a New va ?". 在这种情况下,问题是:“当unstream创建New va时,我应该使用哪个Vector va实例?”。 This can be resolved either by putting an annotation on run or unstream , but it looks as though an annotation on unstream would be less (finger) typing. 可以通过在rununstream上添加注释来解决此问题,但是看起来unstream上的注释的unstream会更少(手指)。 Something like this: 像这样:

f = run . (unstream :: Stream Int -> New {- put something concrete here -} Int) . singleton $ 42

It is the show . read 这是show . read show . read problem, but with a twist. show . read问题,但有一个转折。

The two functions we are composing here are 我们在这里组成的两个函数是

unstream :: forall s v a. (Vector v) => Stream a -> New v a
run :: forall s v' a'. New v' a' -> ST s (Mutable v' s a')

Composing them yields New va ~ New v' a' , and since New is a datatype, it is injective; 组成它们会产生New va ~ New v' a' ,并且由于New是数据类型,因此它是单射的; thus we have v ~ v' and a ~ a' , for: 因此我们有v ~ v'a ~ a'为:

run . unstream :: forall s v a. (Vector v) => Stream a -> ST s (Mutable v s a)

However, the choice of v is unspecified by the type Stream a -> ST s (Mutable vsa) , since Mutable is a type family, and is thus not injective. 但是, v的选择未由Stream a -> ST s (Mutable vsa)类型指定,因为Mutable是类型族,因此不是单射的。 This is where it becomes like show . read :: forall a. (Show a, Read a) => String -> String 这就是show . read :: forall a. (Show a, Read a) => String -> String show . read :: forall a. (Show a, Read a) => String -> String show . read :: forall a. (Show a, Read a) => String -> String ; show . read :: forall a. (Show a, Read a) => String -> String ; it is just harder to see because v seems to occur in the type. 很难看到,因为v似乎出现在类型中。

Think about what happens when you use it at a more concrete type, eg 想一想当您将其用于更具体的类型时会发生什么情况,例如

run . unstream :: forall s. Stream Int -> ST s (MVector s a)

there is no possible way to know what v is supposed to be just from Mutable v ~ MVector . 无法通过Mutable v ~ MVector知道v应该是什么。

All this suggests a way to type run . unstream . singleton 所有这些都暗示了一种键入run . unstream . singleton run . unstream . singleton run . unstream . singleton polymorphically, without pre-committing to a choice of v , by just requiring it to be passed at call sites: run . unstream . singleton态多态,无需预先承诺对v的选择,只需要求将其传递给呼叫站点即可:

{- LANGUAGE ScopedTypeVariables #-}

f :: forall s v a. (Vector v a) => Proxy v -> a -> ST s (Mutable v s a)
f _ = run . (unstream :: Stream a -> New v a) . singleton

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

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