Quite confused by simple transformations on this code not working

Strange little bit of code: http://moonpatio.com:8080/fastcgi/hpaste.fcgi/view?id=829#a829 If I do any of the following, all of which seem natural to me, it fails to typecheck: 1. move f out of the 'where' clause (with or without a type signature) 2. put the same type signature on f as is on (/\) 3. replace f with (/\) completely What's going on here?

Andrew Wagner wrote:
Strange little bit of code: http://moonpatio.com:8080/fastcgi/hpaste.fcgi/view?id=829#a829
If I do any of the following, all of which seem natural to me, it fails to typecheck:
1. move f out of the 'where' clause (with or without a type signature) 2. put the same type signature on f as is on (/\) 3. replace f with (/\) completely
What's going on here?
> :t (nub .) . (++) (nub .) . (++) :: (Eq a) => [a] -> [a] -> [a] > :t foldr (map . (nub .) . (++)) foldr (map . (nub .) . (++)) :: (Eq a) => [[a]] -> [[a]] -> [[a]] The type you give to (/\) is more restrictive than the type of the expression, and f uses the generality of the expression. -- Live well, ~wren

So...there's just no good way to avoid the duplication?
On Tue, Jan 20, 2009 at 11:10 PM, wren ng thornton
Andrew Wagner wrote:
Strange little bit of code: http://moonpatio.com:8080/fastcgi/hpaste.fcgi/view?id=829#a829
If I do any of the following, all of which seem natural to me, it fails to typecheck:
1. move f out of the 'where' clause (with or without a type signature) 2. put the same type signature on f as is on (/\) 3. replace f with (/\) completely
What's going on here?
:t (nub .) . (++) (nub .) . (++) :: (Eq a) => [a] -> [a] -> [a]
:t foldr (map . (nub .) . (++)) foldr (map . (nub .) . (++)) :: (Eq a) => [[a]] -> [[a]] -> [[a]]
The type you give to (/\) is more restrictive than the type of the expression, and f uses the generality of the expression.
-- Live well, ~wren _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Instead of declaring (/\) :: Eq a => Sentence a -> Sentence a ->
Sentence a, you could say (/\) :: Eq a -> [a] -> [a] -> [a]. Then it
would work in both places. ([a] -> [a] -> [a] is a more general type
than [[Term a]] -> [[Term a]] -> [[Term a]], so functions with the
former type can be used in place of functions of the latter type but
not vice versa.)
Alex
2009/1/20 Andrew Wagner
So...there's just no good way to avoid the duplication?
On Tue, Jan 20, 2009 at 11:10 PM, wren ng thornton
wrote: Andrew Wagner wrote:
Strange little bit of code: http://moonpatio.com:8080/fastcgi/hpaste.fcgi/view?id=829#a829
If I do any of the following, all of which seem natural to me, it fails to typecheck:
1. move f out of the 'where' clause (with or without a type signature) 2. put the same type signature on f as is on (/\) 3. replace f with (/\) completely
What's going on here?
:t (nub .) . (++) (nub .) . (++) :: (Eq a) => [a] -> [a] -> [a]
:t foldr (map . (nub .) . (++)) foldr (map . (nub .) . (++)) :: (Eq a) => [[a]] -> [[a]] -> [[a]]
The type you give to (/\) is more restrictive than the type of the expression, and f uses the generality of the expression.
-- Live well, ~wren _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Or if the specificity of (/\) is important to you, you could define f
at the global scope using that type, not export it, then declare (/\)
as equal to f but with a more restrictive type.
On Wed, Jan 21, 2009 at 5:45 AM, Alexander Dunlap
Instead of declaring (/\) :: Eq a => Sentence a -> Sentence a -> Sentence a, you could say (/\) :: Eq a -> [a] -> [a] -> [a]. Then it would work in both places. ([a] -> [a] -> [a] is a more general type than [[Term a]] -> [[Term a]] -> [[Term a]], so functions with the former type can be used in place of functions of the latter type but not vice versa.)
Alex
2009/1/20 Andrew Wagner
: So...there's just no good way to avoid the duplication?
On Tue, Jan 20, 2009 at 11:10 PM, wren ng thornton
wrote: Andrew Wagner wrote:
Strange little bit of code: http://moonpatio.com:8080/fastcgi/hpaste.fcgi/view?id=829#a829
If I do any of the following, all of which seem natural to me, it fails to typecheck:
1. move f out of the 'where' clause (with or without a type signature) 2. put the same type signature on f as is on (/\) 3. replace f with (/\) completely
What's going on here?
:t (nub .) . (++) (nub .) . (++) :: (Eq a) => [a] -> [a] -> [a]
:t foldr (map . (nub .) . (++)) foldr (map . (nub .) . (++)) :: (Eq a) => [[a]] -> [[a]] -> [[a]]
The type you give to (/\) is more restrictive than the type of the expression, and f uses the generality of the expression.
-- Live well, ~wren _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
participants (4)
-
Alexander Dunlap
-
Andrew Wagner
-
Svein Ove Aas
-
wren ng thornton