Control.Arrow:为什么"让(a,b)=(第一,第二)"失败?

Sav*_*xey 8 haskell functional-programming arrows

我想要的是写这样的东西:

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
Run Code Online (Sandbox Code Playgroud)

pha*_*dej 2

很快,您尝试构建 GHC 无法推断的谓语类型。你可以做:

\n\n
\xce\xbb 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))\n\xce\xbb Control.Arrow > :t a\na :: Arrow a => a b b -> a (b, b) (b, b)\n\xce\xbb Control.Arrow > :t b\nb :: Arrow a => a b b -> a (b, b) (b, b)\n
Run Code Online (Sandbox Code Playgroud)\n\n

或者

\n\n
:set -XImpredicativeTypes \n\xce\xbb 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))\n\xce\xbb Control.Arrow > :t a\na :: Arrow a => a b b -> a (b, b) (b, b)\n\xce\xbb Control.Arrow > :t b\nb :: Arrow a => a b b -> a (b, b) (b, b)\n
Run Code Online (Sandbox Code Playgroud)\n\n

但你不能这样做:

\n\n
\xce\xbb 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))\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n\n

为了隔离问题,可以这样做:

\n\n
\xce\xbb 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));\n\xce\xbb Control.Arrow > :t p\np :: (Arrow a', Arrow a) =>\n     (a b b -> a (b, b) (b, b), a' b b -> a' (b, b) (b, b))\n
Run Code Online (Sandbox Code Playgroud)\n\n

但是当你尝试将其绑定到模式时:

\n\n
\xce\xbb Control.Arrow > let (a, b) = p\n
Run Code Online (Sandbox Code Playgroud)\n\n

它失败。约束位于对类型之外,并且对于该对的其他半部分来说是多余的,如下所示

\n\n
\xce\xbb Control.Arrow > :set -XImpredicativeTypes \n\xce\xbb 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))\n\xce\xbb Control.Arrow > let (a, b) = p\n
Run Code Online (Sandbox Code Playgroud)\n\n

作品。

\n\n
\n\n

简单的例子:

\n\n
\xce\xbb Prelude Data.Monoid > :t (mappend, ())\n(mappend, ()) :: Monoid a => (a -> a -> a, ())\n\xce\xbb Prelude Data.Monoid > let (a, b) = (mappend, ())\n\n<interactive>:12:5:\n    No instance for (Monoid a0)\n      arising from the ambiguity check for \xe2\x80\x98b\xe2\x80\x99\n    The type variable \xe2\x80\x98a0\xe2\x80\x99 is ambiguous\n    When checking that \xe2\x80\x98b\xe2\x80\x99 has the inferred type \xe2\x80\x98()\xe2\x80\x99\n    Probable cause: the inferred type is ambiguous\n
Run Code Online (Sandbox Code Playgroud)\n\n

a必须携带约束,但的类型中没有(),即Monoid a => ()是二义性类型。

\n\n
\n\n

注意:let (a,b) = ((+), (*))似乎有效。我不知道为什么以及如何Num受到特殊对待:

\n\n
\xce\xbb Prelude Data.Monoid > let x = () ::  Num a => ()\n\xce\xbb Prelude Data.Monoid > :t x\nx :: ()\n\xce\xbb Prelude Data.Monoid > let x = () :: Monoid m => ()\n\n<interactive>:12:9:\n    No instance for (Monoid m0)\n    ...\n
Run Code Online (Sandbox Code Playgroud)\n