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)
很快,您尝试构建 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)\nRun 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)\nRun 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))\nRun Code Online (Sandbox Code Playgroud)\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))\nRun Code Online (Sandbox Code Playgroud)\n\n但是当你尝试将其绑定到模式时:
\n\n\xce\xbb Control.Arrow > let (a, b) = p\nRun 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\nRun Code Online (Sandbox Code Playgroud)\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\nRun Code Online (Sandbox Code Playgroud)\n\na必须携带约束,但的类型中没有(),即Monoid a => ()是二义性类型。
注意:let (a,b) = ((+), (*))似乎有效。我不知道为什么以及如何Num受到特殊对待:
\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 ...\nRun Code Online (Sandbox Code Playgroud)\n