Control.Arrow: Why "let (a, b) = (first, second)" fails?

I want to write something like this:

let (a,b) = if *condition* then (first, second) else (second, first)

I found out that I cannot even write this:

let (a,b) = (first,second)

Error with error:

  <interactive>:7:5: Could not deduce (Arrow a0) from the context (Arrow a) bound by the inferred type for `a': Arrow a => abc -> 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 :: * -> * -> *) bc d. Arrow a => abc -> 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 => abc -> 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 :: * -> * -> *) bc d. Arrow a => abc -> a (d, b) (d, c) Probable cause: the inferred type is ambiguous 
+8
functional-programming haskell arrows
source share
2 answers

Soon you are trying to build an Impredicative type that the GHC cannot do. You can do:

 位 Control.Arrow > let (a,b) = (first, second) :: Arrow a => (abb -> a (b, b) (b, b), abb -> a (b, b) (b, b)) 位 Control.Arrow > :ta a :: Arrow a => abb -> a (b, b) (b, b) 位 Control.Arrow > :tb b :: Arrow a => abb -> a (b, b) (b, b) 

or

 :set -XImpredicativeTypes 位 Control.Arrow > let (a,b) = (first, second) :: (Arrow a => abb -> a (b, b) (b, b), Arrow a => abb -> a (b, b) (b, b)) 位 Control.Arrow > :ta a :: Arrow a => abb -> a (b, b) (b, b) 位 Control.Arrow > :tb b :: Arrow a => abb -> a (b, b) (b, b) 

but you cannot do:

 位 Control.Arrow > let (a,b) = (first, second) :: (Arrow a, Arrow a') => (abb -> a (b, b) (b, b), a' bb -> a' (b, b) (b, b)) 

To isolate the problem, this works:

 位 Control.Arrow > let p = (first, second) :: (Arrow a, Arrow a') => (abb -> a (b, b) (b, b), a' bb -> a' (b, b) (b, b)); 位 Control.Arrow > :tp p :: (Arrow a', Arrow a) => (abb -> a (b, b) (b, b), a' bb -> a' (b, b) (b, b)) 

but when you try to associate this with a pattern:

 位 Control.Arrow > let (a, b) = p 

he fails. The restrictions are outside the type of pair and are redundant for the other half of the pair, since

 位 Control.Arrow > :set -XImpredicativeTypes 位 Control.Arrow > let p = (first, second) :: (Arrow a => abb -> a (b, b) (b, b), Arrow a => abb -> a (b, b) (b, b)) 位 Control.Arrow > let (a, b) = p 

work.


A simple example:

 位 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 need to be transferred, but type () does not have a , i.e. Monoid a => () is an ambiguous type.


Note: let (a,b) = ((+), (*)) seems to work. I have no idea why and how Num handled specifically:

 位 Prelude Data.Monoid > let x = () :: Num a => () 位 Prelude Data.Monoid > :tx x :: () 位 Prelude Data.Monoid > let x = () :: Monoid m => () <interactive>:12:9: No instance for (Monoid m0) ... 
+2
source share

It looks like you are using monomorphism restriction . This is just a limitation of Haskell type inference, and you can get around it by adding an explicit type signature.

 import Control.Arrow foo :: (Arrow a, Arrow a1) => (abc -> a (b, d) (c, d), a1 b1 c1 -> a1 (d1, b1) (d1, c1)) foo = (first, second) 

This type of code is great for a type signature for foo , but gives a compilation error for the "ambiguous variable" if you delete it.

By the way, the type signature I used was selected :t (first, second) in GHCI. Since you want (first, second) and (second, first) be of the same type, you probably want to use a more specific type in your annotation, like the following:

 foo :: (Arrow a) => (abb -> a (b, b) (b, b), abb -> a (b, b) (b, b)) 
+1
source share

All Articles