Control.Arrow:为什么 "let (a,b) = (first,second)" 失败了?
Control.Arrow: Why "let (a,b) = (first,second)" fails?
我想要的是这样写:
let (a,b) = if *condition* then (first, second) else (second, first)
我发现我连这个都不会写:
let (a,b) = (first,second)
失败并出现错误:
<interactive>:7:5:
Could not deduce (Arrow a0)
from the context (Arrow a)
bound by the inferred type for `a':
Arrow a => a b c -> a (b, d) (c, d)
at <interactive>:7:5-26
The type variable `a0' is ambiguous
When checking that `a' has the inferred type
a :: forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
Probable cause: the inferred type is ambiguous
<interactive>:7:5:
Could not deduce (Arrow a0)
from the context (Arrow a)
bound by the inferred type for `b':
Arrow a => a b c -> a (d, b) (d, c)
at <interactive>:7:5-26
The type variable `a0' is ambiguous
When checking that `b' has the inferred type
b :: forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
Probable cause: the inferred type is ambiguous
看起来你是 运行 monomorphism restriction。这只是 Haskell 类型推断的一个限制,您可以通过添加显式类型签名来绕过它。
import Control.Arrow
foo :: (Arrow a, Arrow a1) => (a b c -> a (b, d) (c, d), a1 b1 c1 -> a1 (d1, b1) (d1, c1))
foo = (first, second)
此代码可以通过 foo
的类型签名进行类型检查,但如果删除它,则会出现 "ambiguous variable" 编译错误。
顺便说一句,我使用的类型签名是 :t (first, second)
在 GHCI 中推断出的类型签名。由于您希望 (first, second)
和 (second, first)
具有相同的类型,因此您可能希望在注释中使用更具体的类型,例如以下类型:
foo :: (Arrow a) => (a b b -> a (b, b) (b, b), a b b -> a (b, b) (b, b))
很快,您尝试构造 GHC 无法推断的命令类型。你可以这样做:
λ Control.Arrow > let (a,b) = (first, second) :: Arrow a => (a b b -> a (b, b) (b, b), a b b -> a (b, b) (b, b))
λ Control.Arrow > :t a
a :: Arrow a => a b b -> a (b, b) (b, b)
λ Control.Arrow > :t b
b :: Arrow a => a b b -> a (b, b) (b, b)
或
:set -XImpredicativeTypes
λ Control.Arrow > let (a,b) = (first, second) :: (Arrow a => a b b -> a (b, b) (b, b), Arrow a => a b b -> a (b, b) (b, b))
λ Control.Arrow > :t a
a :: Arrow a => a b b -> a (b, b) (b, b)
λ Control.Arrow > :t b
b :: Arrow a => a b b -> a (b, b) (b, b)
但你不能这样做:
λ Control.Arrow > let (a,b) = (first, second) :: (Arrow a, Arrow a') => (a b b -> a (b, b) (b, b), a' b b -> a' (b, b) (b, b))
为了隔离问题,这个有效:
λ Control.Arrow > let p = (first, second) :: (Arrow a, Arrow a') => (a b b -> a (b, b) (b, b), a' b b -> a' (b, b) (b, b));
λ Control.Arrow > :t p
p :: (Arrow a', Arrow a) =>
(a b b -> a (b, b) (b, b), a' b b -> a' (b, b) (b, b))
但是当您尝试将其绑定到模式时:
λ Control.Arrow > let (a, b) = p
它失败了。约束在对类型之外,并且对于对的另一半是多余的,如
λ Control.Arrow > :set -XImpredicativeTypes
λ Control.Arrow > let p = (first, second) :: (Arrow a => a b b -> a (b, b) (b, b), Arrow a => a b b -> a (b, b) (b, b))
λ Control.Arrow > let (a, b) = p
有效。
简单示例:
λ Prelude Data.Monoid > :t (mappend, ())
(mappend, ()) :: Monoid a => (a -> a -> a, ())
λ Prelude Data.Monoid > let (a, b) = (mappend, ())
<interactive>:12:5:
No instance for (Monoid a0)
arising from the ambiguity check for ‘b’
The type variable ‘a0’ is ambiguous
When checking that ‘b’ has the inferred type ‘()’
Probable cause: the inferred type is ambiguous
要带constraints过来,但是()
的类型里没有a
,即Monoid a => ()
是有歧义的类型
注意:let (a,b) = ((+), (*))
似乎有效。我不知道 Num
为什么以及如何被特殊对待:
λ Prelude Data.Monoid > let x = () :: Num a => ()
λ Prelude Data.Monoid > :t x
x :: ()
λ Prelude Data.Monoid > let x = () :: Monoid m => ()
<interactive>:12:9:
No instance for (Monoid m0)
...
我想要的是这样写:
let (a,b) = if *condition* then (first, second) else (second, first)
我发现我连这个都不会写:
let (a,b) = (first,second)
失败并出现错误:
<interactive>:7:5:
Could not deduce (Arrow a0)
from the context (Arrow a)
bound by the inferred type for `a':
Arrow a => a b c -> a (b, d) (c, d)
at <interactive>:7:5-26
The type variable `a0' is ambiguous
When checking that `a' has the inferred type
a :: forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
Probable cause: the inferred type is ambiguous
<interactive>:7:5:
Could not deduce (Arrow a0)
from the context (Arrow a)
bound by the inferred type for `b':
Arrow a => a b c -> a (d, b) (d, c)
at <interactive>:7:5-26
The type variable `a0' is ambiguous
When checking that `b' has the inferred type
b :: forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
Probable cause: the inferred type is ambiguous
看起来你是 运行 monomorphism restriction。这只是 Haskell 类型推断的一个限制,您可以通过添加显式类型签名来绕过它。
import Control.Arrow
foo :: (Arrow a, Arrow a1) => (a b c -> a (b, d) (c, d), a1 b1 c1 -> a1 (d1, b1) (d1, c1))
foo = (first, second)
此代码可以通过 foo
的类型签名进行类型检查,但如果删除它,则会出现 "ambiguous variable" 编译错误。
顺便说一句,我使用的类型签名是 :t (first, second)
在 GHCI 中推断出的类型签名。由于您希望 (first, second)
和 (second, first)
具有相同的类型,因此您可能希望在注释中使用更具体的类型,例如以下类型:
foo :: (Arrow a) => (a b b -> a (b, b) (b, b), a b b -> a (b, b) (b, b))
很快,您尝试构造 GHC 无法推断的命令类型。你可以这样做:
λ Control.Arrow > let (a,b) = (first, second) :: Arrow a => (a b b -> a (b, b) (b, b), a b b -> a (b, b) (b, b))
λ Control.Arrow > :t a
a :: Arrow a => a b b -> a (b, b) (b, b)
λ Control.Arrow > :t b
b :: Arrow a => a b b -> a (b, b) (b, b)
或
:set -XImpredicativeTypes
λ Control.Arrow > let (a,b) = (first, second) :: (Arrow a => a b b -> a (b, b) (b, b), Arrow a => a b b -> a (b, b) (b, b))
λ Control.Arrow > :t a
a :: Arrow a => a b b -> a (b, b) (b, b)
λ Control.Arrow > :t b
b :: Arrow a => a b b -> a (b, b) (b, b)
但你不能这样做:
λ Control.Arrow > let (a,b) = (first, second) :: (Arrow a, Arrow a') => (a b b -> a (b, b) (b, b), a' b b -> a' (b, b) (b, b))
为了隔离问题,这个有效:
λ Control.Arrow > let p = (first, second) :: (Arrow a, Arrow a') => (a b b -> a (b, b) (b, b), a' b b -> a' (b, b) (b, b));
λ Control.Arrow > :t p
p :: (Arrow a', Arrow a) =>
(a b b -> a (b, b) (b, b), a' b b -> a' (b, b) (b, b))
但是当您尝试将其绑定到模式时:
λ Control.Arrow > let (a, b) = p
它失败了。约束在对类型之外,并且对于对的另一半是多余的,如
λ Control.Arrow > :set -XImpredicativeTypes
λ Control.Arrow > let p = (first, second) :: (Arrow a => a b b -> a (b, b) (b, b), Arrow a => a b b -> a (b, b) (b, b))
λ Control.Arrow > let (a, b) = p
有效。
简单示例:
λ Prelude Data.Monoid > :t (mappend, ())
(mappend, ()) :: Monoid a => (a -> a -> a, ())
λ Prelude Data.Monoid > let (a, b) = (mappend, ())
<interactive>:12:5:
No instance for (Monoid a0)
arising from the ambiguity check for ‘b’
The type variable ‘a0’ is ambiguous
When checking that ‘b’ has the inferred type ‘()’
Probable cause: the inferred type is ambiguous
要带constraints过来,但是()
的类型里没有a
,即Monoid a => ()
是有歧义的类型
注意:let (a,b) = ((+), (*))
似乎有效。我不知道 Num
为什么以及如何被特殊对待:
λ Prelude Data.Monoid > let x = () :: Num a => ()
λ Prelude Data.Monoid > :t x
x :: ()
λ Prelude Data.Monoid > let x = () :: Monoid m => ()
<interactive>:12:9:
No instance for (Monoid m0)
...