ViewPatterns affects typechecking in an unpredictable manner










4















Consider the following code snippet:



import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Vector.Unboxed as UV
import qualified Data.Vector.Generic as V

bar :: Int -> UV.Vector Char -> (Text, Text)
bar i v = (t_pre, t_post)
where
f = T.pack . V.toList
(t_pre, t_post) = ((x, y) -> (f x, f y)) $ V.splitAt i v


This compiles ok as you might expect. However, if you replace the function calls with view patterns, you get a type error.



-# LANGUAGE ViewPatterns #-

import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Vector.Unboxed as UV
import qualified Data.Vector.Generic as V

bar :: Int -> UV.Vector Char -> (Text, Text)
bar i v = (t_pre, t_post)
where
f = T.pack . V.toList
(f -> t_pre, f -> t_post) = V.splitAt i v


This prints the following message (with -fprint-potential-instances):



 • Ambiguous type variable ‘v0’ arising from a use of ‘V.toList’
prevents the constraint ‘(V.Vector v0 Char)’ from being solved.
Relevant bindings include
f :: v0 Char -> Text (bound at Weird.hs:11:5)
Probable fix: use a type annotation to specify what ‘v0’ should be.
These potential instances exist:
instance V.Vector UV.Vector Char
-- Defined in ‘Data.Vector.Unboxed.Base’
...plus one instance involving out-of-scope types
instance primitive-0.6.3.0:Data.Primitive.Types.Prim a =>
V.Vector Data.Vector.Primitive.Vector a
-- Defined in ‘Data.Vector.Primitive’
• In the second argument of ‘(.)’, namely ‘V.toList’
In the expression: T.pack . V.toList
In an equation for ‘f’: f = T.pack . V.toList
|
11 | f = T.pack . V.toList
| ^^^^^^^^

Weird.hs:13:6: error:
Variable not in scope: f :: UV.Vector Char -> t
|
13 | (f -> t_pre, f -> t_post) = V.splitAt i v
| ^

Weird.hs:13:18: error:
Variable not in scope: f :: UV.Vector Char -> t1
|
13 | (f -> t_pre, f -> t_post) = V.splitAt i v
| ^


My understanding is that both the ways of expressing things are entirely equivalent, because a view pattern is just function application without naming the bound variable. Am I misunderstanding view patterns? Is it the desugaring that is interacting with the type checker in an unexpected manner? If I inline the definition of f at both the call sites, the type error goes away.



I've tested this with GHCi 8.4.3.




Update: This is a compiler bug. See GHC Trac #14293 for more details.










share|improve this question
























  • As far as I know ViewPatterns is kind of syntactic sugar for function pattern matching, Not function application. The sintax is function -> Constructor. Try by matching the pattern ( , )

    – Luis Morillo
    Nov 14 '18 at 8:44











  • You can't pattern match on a function though, you can only apply a function. f = show. Then (f -> x, f -> y) = (1, 2) in GHCi after :set -XViewPatterns. It will give you x == "1" and y == "2".

    – theindigamer
    Nov 14 '18 at 8:48











  • Based on the answers, it seems like a bug. I've created a ticket for confirmation.

    – theindigamer
    Nov 14 '18 at 9:31















4















Consider the following code snippet:



import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Vector.Unboxed as UV
import qualified Data.Vector.Generic as V

bar :: Int -> UV.Vector Char -> (Text, Text)
bar i v = (t_pre, t_post)
where
f = T.pack . V.toList
(t_pre, t_post) = ((x, y) -> (f x, f y)) $ V.splitAt i v


This compiles ok as you might expect. However, if you replace the function calls with view patterns, you get a type error.



-# LANGUAGE ViewPatterns #-

import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Vector.Unboxed as UV
import qualified Data.Vector.Generic as V

bar :: Int -> UV.Vector Char -> (Text, Text)
bar i v = (t_pre, t_post)
where
f = T.pack . V.toList
(f -> t_pre, f -> t_post) = V.splitAt i v


This prints the following message (with -fprint-potential-instances):



 • Ambiguous type variable ‘v0’ arising from a use of ‘V.toList’
prevents the constraint ‘(V.Vector v0 Char)’ from being solved.
Relevant bindings include
f :: v0 Char -> Text (bound at Weird.hs:11:5)
Probable fix: use a type annotation to specify what ‘v0’ should be.
These potential instances exist:
instance V.Vector UV.Vector Char
-- Defined in ‘Data.Vector.Unboxed.Base’
...plus one instance involving out-of-scope types
instance primitive-0.6.3.0:Data.Primitive.Types.Prim a =>
V.Vector Data.Vector.Primitive.Vector a
-- Defined in ‘Data.Vector.Primitive’
• In the second argument of ‘(.)’, namely ‘V.toList’
In the expression: T.pack . V.toList
In an equation for ‘f’: f = T.pack . V.toList
|
11 | f = T.pack . V.toList
| ^^^^^^^^

Weird.hs:13:6: error:
Variable not in scope: f :: UV.Vector Char -> t
|
13 | (f -> t_pre, f -> t_post) = V.splitAt i v
| ^

Weird.hs:13:18: error:
Variable not in scope: f :: UV.Vector Char -> t1
|
13 | (f -> t_pre, f -> t_post) = V.splitAt i v
| ^


My understanding is that both the ways of expressing things are entirely equivalent, because a view pattern is just function application without naming the bound variable. Am I misunderstanding view patterns? Is it the desugaring that is interacting with the type checker in an unexpected manner? If I inline the definition of f at both the call sites, the type error goes away.



I've tested this with GHCi 8.4.3.




Update: This is a compiler bug. See GHC Trac #14293 for more details.










share|improve this question
























  • As far as I know ViewPatterns is kind of syntactic sugar for function pattern matching, Not function application. The sintax is function -> Constructor. Try by matching the pattern ( , )

    – Luis Morillo
    Nov 14 '18 at 8:44











  • You can't pattern match on a function though, you can only apply a function. f = show. Then (f -> x, f -> y) = (1, 2) in GHCi after :set -XViewPatterns. It will give you x == "1" and y == "2".

    – theindigamer
    Nov 14 '18 at 8:48











  • Based on the answers, it seems like a bug. I've created a ticket for confirmation.

    – theindigamer
    Nov 14 '18 at 9:31













4












4








4


1






Consider the following code snippet:



import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Vector.Unboxed as UV
import qualified Data.Vector.Generic as V

bar :: Int -> UV.Vector Char -> (Text, Text)
bar i v = (t_pre, t_post)
where
f = T.pack . V.toList
(t_pre, t_post) = ((x, y) -> (f x, f y)) $ V.splitAt i v


This compiles ok as you might expect. However, if you replace the function calls with view patterns, you get a type error.



-# LANGUAGE ViewPatterns #-

import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Vector.Unboxed as UV
import qualified Data.Vector.Generic as V

bar :: Int -> UV.Vector Char -> (Text, Text)
bar i v = (t_pre, t_post)
where
f = T.pack . V.toList
(f -> t_pre, f -> t_post) = V.splitAt i v


This prints the following message (with -fprint-potential-instances):



 • Ambiguous type variable ‘v0’ arising from a use of ‘V.toList’
prevents the constraint ‘(V.Vector v0 Char)’ from being solved.
Relevant bindings include
f :: v0 Char -> Text (bound at Weird.hs:11:5)
Probable fix: use a type annotation to specify what ‘v0’ should be.
These potential instances exist:
instance V.Vector UV.Vector Char
-- Defined in ‘Data.Vector.Unboxed.Base’
...plus one instance involving out-of-scope types
instance primitive-0.6.3.0:Data.Primitive.Types.Prim a =>
V.Vector Data.Vector.Primitive.Vector a
-- Defined in ‘Data.Vector.Primitive’
• In the second argument of ‘(.)’, namely ‘V.toList’
In the expression: T.pack . V.toList
In an equation for ‘f’: f = T.pack . V.toList
|
11 | f = T.pack . V.toList
| ^^^^^^^^

Weird.hs:13:6: error:
Variable not in scope: f :: UV.Vector Char -> t
|
13 | (f -> t_pre, f -> t_post) = V.splitAt i v
| ^

Weird.hs:13:18: error:
Variable not in scope: f :: UV.Vector Char -> t1
|
13 | (f -> t_pre, f -> t_post) = V.splitAt i v
| ^


My understanding is that both the ways of expressing things are entirely equivalent, because a view pattern is just function application without naming the bound variable. Am I misunderstanding view patterns? Is it the desugaring that is interacting with the type checker in an unexpected manner? If I inline the definition of f at both the call sites, the type error goes away.



I've tested this with GHCi 8.4.3.




Update: This is a compiler bug. See GHC Trac #14293 for more details.










share|improve this question
















Consider the following code snippet:



import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Vector.Unboxed as UV
import qualified Data.Vector.Generic as V

bar :: Int -> UV.Vector Char -> (Text, Text)
bar i v = (t_pre, t_post)
where
f = T.pack . V.toList
(t_pre, t_post) = ((x, y) -> (f x, f y)) $ V.splitAt i v


This compiles ok as you might expect. However, if you replace the function calls with view patterns, you get a type error.



-# LANGUAGE ViewPatterns #-

import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Vector.Unboxed as UV
import qualified Data.Vector.Generic as V

bar :: Int -> UV.Vector Char -> (Text, Text)
bar i v = (t_pre, t_post)
where
f = T.pack . V.toList
(f -> t_pre, f -> t_post) = V.splitAt i v


This prints the following message (with -fprint-potential-instances):



 • Ambiguous type variable ‘v0’ arising from a use of ‘V.toList’
prevents the constraint ‘(V.Vector v0 Char)’ from being solved.
Relevant bindings include
f :: v0 Char -> Text (bound at Weird.hs:11:5)
Probable fix: use a type annotation to specify what ‘v0’ should be.
These potential instances exist:
instance V.Vector UV.Vector Char
-- Defined in ‘Data.Vector.Unboxed.Base’
...plus one instance involving out-of-scope types
instance primitive-0.6.3.0:Data.Primitive.Types.Prim a =>
V.Vector Data.Vector.Primitive.Vector a
-- Defined in ‘Data.Vector.Primitive’
• In the second argument of ‘(.)’, namely ‘V.toList’
In the expression: T.pack . V.toList
In an equation for ‘f’: f = T.pack . V.toList
|
11 | f = T.pack . V.toList
| ^^^^^^^^

Weird.hs:13:6: error:
Variable not in scope: f :: UV.Vector Char -> t
|
13 | (f -> t_pre, f -> t_post) = V.splitAt i v
| ^

Weird.hs:13:18: error:
Variable not in scope: f :: UV.Vector Char -> t1
|
13 | (f -> t_pre, f -> t_post) = V.splitAt i v
| ^


My understanding is that both the ways of expressing things are entirely equivalent, because a view pattern is just function application without naming the bound variable. Am I misunderstanding view patterns? Is it the desugaring that is interacting with the type checker in an unexpected manner? If I inline the definition of f at both the call sites, the type error goes away.



I've tested this with GHCi 8.4.3.




Update: This is a compiler bug. See GHC Trac #14293 for more details.







haskell ghc






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 14 '18 at 10:34







theindigamer

















asked Nov 14 '18 at 7:10









theindigamertheindigamer

704519




704519












  • As far as I know ViewPatterns is kind of syntactic sugar for function pattern matching, Not function application. The sintax is function -> Constructor. Try by matching the pattern ( , )

    – Luis Morillo
    Nov 14 '18 at 8:44











  • You can't pattern match on a function though, you can only apply a function. f = show. Then (f -> x, f -> y) = (1, 2) in GHCi after :set -XViewPatterns. It will give you x == "1" and y == "2".

    – theindigamer
    Nov 14 '18 at 8:48











  • Based on the answers, it seems like a bug. I've created a ticket for confirmation.

    – theindigamer
    Nov 14 '18 at 9:31

















  • As far as I know ViewPatterns is kind of syntactic sugar for function pattern matching, Not function application. The sintax is function -> Constructor. Try by matching the pattern ( , )

    – Luis Morillo
    Nov 14 '18 at 8:44











  • You can't pattern match on a function though, you can only apply a function. f = show. Then (f -> x, f -> y) = (1, 2) in GHCi after :set -XViewPatterns. It will give you x == "1" and y == "2".

    – theindigamer
    Nov 14 '18 at 8:48











  • Based on the answers, it seems like a bug. I've created a ticket for confirmation.

    – theindigamer
    Nov 14 '18 at 9:31
















As far as I know ViewPatterns is kind of syntactic sugar for function pattern matching, Not function application. The sintax is function -> Constructor. Try by matching the pattern ( , )

– Luis Morillo
Nov 14 '18 at 8:44





As far as I know ViewPatterns is kind of syntactic sugar for function pattern matching, Not function application. The sintax is function -> Constructor. Try by matching the pattern ( , )

– Luis Morillo
Nov 14 '18 at 8:44













You can't pattern match on a function though, you can only apply a function. f = show. Then (f -> x, f -> y) = (1, 2) in GHCi after :set -XViewPatterns. It will give you x == "1" and y == "2".

– theindigamer
Nov 14 '18 at 8:48





You can't pattern match on a function though, you can only apply a function. f = show. Then (f -> x, f -> y) = (1, 2) in GHCi after :set -XViewPatterns. It will give you x == "1" and y == "2".

– theindigamer
Nov 14 '18 at 8:48













Based on the answers, it seems like a bug. I've created a ticket for confirmation.

– theindigamer
Nov 14 '18 at 9:31





Based on the answers, it seems like a bug. I've created a ticket for confirmation.

– theindigamer
Nov 14 '18 at 9:31












2 Answers
2






active

oldest

votes


















4














You have a problem with f which is caused by the monomorphism restriction. If you eta expand f, give it a type signature, or turn on NoMonomorphismRestriction, then this error will go away.



But you're still left with these errors, which came as a surprise to me!



Weird.hs:13:6: error:
Variable not in scope: f :: UV.Vector Char -> t
|
13 | (f -> t_pre, f -> t_post) = V.splitAt i v
| ^

Weird.hs:13:18: error:
Variable not in scope: f :: UV.Vector Char -> t1
|
13 | (f -> t_pre, f -> t_post) = V.splitAt i v
| ^


I guess view patterns don't work if they are defined in the same scope. To see if view patterns needed to be top-level, I tried



bar :: Int -> UV.Vector Char -> (Text, Text)
bar i v = let (f -> t_pre, f -> t_post) = V.splitAt i v in (t_pre, t_post)
where
f = T.pack . V.toList


which worked fine. So I tried



f = T.pack . V.toList
(f -> t_pre, f -> t_post) = V.splitAt 0 UV.empty


Which fails with f not in scope.



Finally, if I put those patterns under a function call



f = T.pack . V.toList
g (f -> t_pre, f -> t_post) = V.splitAt 0 UV.empty


then it's fine again. So I guess the rule is that a "value" pattern binding can't use a view pattern which is defined in the same scope. I find that weird, it might even be a bug.






share|improve this answer























  • Note that, weirdly, in some cases we can define f in the same scope (see my answer at the bottom). I have no idea on what triggers the error, and I suspect some interaction with type inference, but it's only a guess.

    – chi
    Nov 14 '18 at 8:59







  • 1





    @chi No, I still get failures for pattern bindings not under a function (there has to be a name for these!). E.g. let f = id ; (f -> x) = () in x fails.

    – luqui
    Nov 14 '18 at 9:01












  • Argh. So that matters as well. Too weird, it must be some bug. Moreover, let f = id in let (f -> x) = () in x works...

    – chi
    Nov 14 '18 at 10:01



















3














This is quite weird indeed. It might be a bug.



Modifying the original code as follows



where
f x = T.pack (V.toList x)
(f -> t_pre, f -> t_post) = V.splitAt i v


makes GHC ask for FlexibleContexts. After doing that, we get a very strange error:



 Variable not in scope: f :: UV.Vector Char -> t
|
12 | (f -> t_pre, f -> t_post) = V.splitAt i v
| ^
Variable not in scope: f :: UV.Vector Char -> t1
|
12 | (f -> t_pre, f -> t_post) = V.splitAt i v
| ^


This seems like a bug to me. f should be in scope there.



Moving f to global scope:



 ...
where
(f -> t_pre, f -> t_post) = V.splitAt i v

f x = T.pack (V.toList x)


The code now works just fine. It even works if we revert the global f to the pointfree definition.



Using an explicit type annotation, as in



where
f :: UV.Vector Char -> Text
f x = T.pack (V.toList x)
(f -> t_pre, f -> t_post) = V.splitAt i v


produces a puzzling error message



• Variable not in scope: f :: UV.Vector Char -> t
• Perhaps you meant ‘f’ (line 12)


I can't understand what's really going on. In GHCi, both these work fine



> let f = id ; foo (f -> x) = x in foo ()
()
> let bar = foo () where f = id ; foo (f -> x) = x in bar
()


Hence, we can use a local f in view patterns. Still, when the type of f needs some more careful type inference (?), then it can not be used in view patterns. This looks like a bug. At the very least, the error message should be more clear.






share|improve this answer




















  • 1





    Answers in stereo :-P

    – luqui
    Nov 14 '18 at 8:59










Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53294823%2fviewpatterns-affects-typechecking-in-an-unpredictable-manner%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









4














You have a problem with f which is caused by the monomorphism restriction. If you eta expand f, give it a type signature, or turn on NoMonomorphismRestriction, then this error will go away.



But you're still left with these errors, which came as a surprise to me!



Weird.hs:13:6: error:
Variable not in scope: f :: UV.Vector Char -> t
|
13 | (f -> t_pre, f -> t_post) = V.splitAt i v
| ^

Weird.hs:13:18: error:
Variable not in scope: f :: UV.Vector Char -> t1
|
13 | (f -> t_pre, f -> t_post) = V.splitAt i v
| ^


I guess view patterns don't work if they are defined in the same scope. To see if view patterns needed to be top-level, I tried



bar :: Int -> UV.Vector Char -> (Text, Text)
bar i v = let (f -> t_pre, f -> t_post) = V.splitAt i v in (t_pre, t_post)
where
f = T.pack . V.toList


which worked fine. So I tried



f = T.pack . V.toList
(f -> t_pre, f -> t_post) = V.splitAt 0 UV.empty


Which fails with f not in scope.



Finally, if I put those patterns under a function call



f = T.pack . V.toList
g (f -> t_pre, f -> t_post) = V.splitAt 0 UV.empty


then it's fine again. So I guess the rule is that a "value" pattern binding can't use a view pattern which is defined in the same scope. I find that weird, it might even be a bug.






share|improve this answer























  • Note that, weirdly, in some cases we can define f in the same scope (see my answer at the bottom). I have no idea on what triggers the error, and I suspect some interaction with type inference, but it's only a guess.

    – chi
    Nov 14 '18 at 8:59







  • 1





    @chi No, I still get failures for pattern bindings not under a function (there has to be a name for these!). E.g. let f = id ; (f -> x) = () in x fails.

    – luqui
    Nov 14 '18 at 9:01












  • Argh. So that matters as well. Too weird, it must be some bug. Moreover, let f = id in let (f -> x) = () in x works...

    – chi
    Nov 14 '18 at 10:01
















4














You have a problem with f which is caused by the monomorphism restriction. If you eta expand f, give it a type signature, or turn on NoMonomorphismRestriction, then this error will go away.



But you're still left with these errors, which came as a surprise to me!



Weird.hs:13:6: error:
Variable not in scope: f :: UV.Vector Char -> t
|
13 | (f -> t_pre, f -> t_post) = V.splitAt i v
| ^

Weird.hs:13:18: error:
Variable not in scope: f :: UV.Vector Char -> t1
|
13 | (f -> t_pre, f -> t_post) = V.splitAt i v
| ^


I guess view patterns don't work if they are defined in the same scope. To see if view patterns needed to be top-level, I tried



bar :: Int -> UV.Vector Char -> (Text, Text)
bar i v = let (f -> t_pre, f -> t_post) = V.splitAt i v in (t_pre, t_post)
where
f = T.pack . V.toList


which worked fine. So I tried



f = T.pack . V.toList
(f -> t_pre, f -> t_post) = V.splitAt 0 UV.empty


Which fails with f not in scope.



Finally, if I put those patterns under a function call



f = T.pack . V.toList
g (f -> t_pre, f -> t_post) = V.splitAt 0 UV.empty


then it's fine again. So I guess the rule is that a "value" pattern binding can't use a view pattern which is defined in the same scope. I find that weird, it might even be a bug.






share|improve this answer























  • Note that, weirdly, in some cases we can define f in the same scope (see my answer at the bottom). I have no idea on what triggers the error, and I suspect some interaction with type inference, but it's only a guess.

    – chi
    Nov 14 '18 at 8:59







  • 1





    @chi No, I still get failures for pattern bindings not under a function (there has to be a name for these!). E.g. let f = id ; (f -> x) = () in x fails.

    – luqui
    Nov 14 '18 at 9:01












  • Argh. So that matters as well. Too weird, it must be some bug. Moreover, let f = id in let (f -> x) = () in x works...

    – chi
    Nov 14 '18 at 10:01














4












4








4







You have a problem with f which is caused by the monomorphism restriction. If you eta expand f, give it a type signature, or turn on NoMonomorphismRestriction, then this error will go away.



But you're still left with these errors, which came as a surprise to me!



Weird.hs:13:6: error:
Variable not in scope: f :: UV.Vector Char -> t
|
13 | (f -> t_pre, f -> t_post) = V.splitAt i v
| ^

Weird.hs:13:18: error:
Variable not in scope: f :: UV.Vector Char -> t1
|
13 | (f -> t_pre, f -> t_post) = V.splitAt i v
| ^


I guess view patterns don't work if they are defined in the same scope. To see if view patterns needed to be top-level, I tried



bar :: Int -> UV.Vector Char -> (Text, Text)
bar i v = let (f -> t_pre, f -> t_post) = V.splitAt i v in (t_pre, t_post)
where
f = T.pack . V.toList


which worked fine. So I tried



f = T.pack . V.toList
(f -> t_pre, f -> t_post) = V.splitAt 0 UV.empty


Which fails with f not in scope.



Finally, if I put those patterns under a function call



f = T.pack . V.toList
g (f -> t_pre, f -> t_post) = V.splitAt 0 UV.empty


then it's fine again. So I guess the rule is that a "value" pattern binding can't use a view pattern which is defined in the same scope. I find that weird, it might even be a bug.






share|improve this answer













You have a problem with f which is caused by the monomorphism restriction. If you eta expand f, give it a type signature, or turn on NoMonomorphismRestriction, then this error will go away.



But you're still left with these errors, which came as a surprise to me!



Weird.hs:13:6: error:
Variable not in scope: f :: UV.Vector Char -> t
|
13 | (f -> t_pre, f -> t_post) = V.splitAt i v
| ^

Weird.hs:13:18: error:
Variable not in scope: f :: UV.Vector Char -> t1
|
13 | (f -> t_pre, f -> t_post) = V.splitAt i v
| ^


I guess view patterns don't work if they are defined in the same scope. To see if view patterns needed to be top-level, I tried



bar :: Int -> UV.Vector Char -> (Text, Text)
bar i v = let (f -> t_pre, f -> t_post) = V.splitAt i v in (t_pre, t_post)
where
f = T.pack . V.toList


which worked fine. So I tried



f = T.pack . V.toList
(f -> t_pre, f -> t_post) = V.splitAt 0 UV.empty


Which fails with f not in scope.



Finally, if I put those patterns under a function call



f = T.pack . V.toList
g (f -> t_pre, f -> t_post) = V.splitAt 0 UV.empty


then it's fine again. So I guess the rule is that a "value" pattern binding can't use a view pattern which is defined in the same scope. I find that weird, it might even be a bug.







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 14 '18 at 8:57









luquiluqui

47.6k6113166




47.6k6113166












  • Note that, weirdly, in some cases we can define f in the same scope (see my answer at the bottom). I have no idea on what triggers the error, and I suspect some interaction with type inference, but it's only a guess.

    – chi
    Nov 14 '18 at 8:59







  • 1





    @chi No, I still get failures for pattern bindings not under a function (there has to be a name for these!). E.g. let f = id ; (f -> x) = () in x fails.

    – luqui
    Nov 14 '18 at 9:01












  • Argh. So that matters as well. Too weird, it must be some bug. Moreover, let f = id in let (f -> x) = () in x works...

    – chi
    Nov 14 '18 at 10:01


















  • Note that, weirdly, in some cases we can define f in the same scope (see my answer at the bottom). I have no idea on what triggers the error, and I suspect some interaction with type inference, but it's only a guess.

    – chi
    Nov 14 '18 at 8:59







  • 1





    @chi No, I still get failures for pattern bindings not under a function (there has to be a name for these!). E.g. let f = id ; (f -> x) = () in x fails.

    – luqui
    Nov 14 '18 at 9:01












  • Argh. So that matters as well. Too weird, it must be some bug. Moreover, let f = id in let (f -> x) = () in x works...

    – chi
    Nov 14 '18 at 10:01

















Note that, weirdly, in some cases we can define f in the same scope (see my answer at the bottom). I have no idea on what triggers the error, and I suspect some interaction with type inference, but it's only a guess.

– chi
Nov 14 '18 at 8:59






Note that, weirdly, in some cases we can define f in the same scope (see my answer at the bottom). I have no idea on what triggers the error, and I suspect some interaction with type inference, but it's only a guess.

– chi
Nov 14 '18 at 8:59





1




1





@chi No, I still get failures for pattern bindings not under a function (there has to be a name for these!). E.g. let f = id ; (f -> x) = () in x fails.

– luqui
Nov 14 '18 at 9:01






@chi No, I still get failures for pattern bindings not under a function (there has to be a name for these!). E.g. let f = id ; (f -> x) = () in x fails.

– luqui
Nov 14 '18 at 9:01














Argh. So that matters as well. Too weird, it must be some bug. Moreover, let f = id in let (f -> x) = () in x works...

– chi
Nov 14 '18 at 10:01






Argh. So that matters as well. Too weird, it must be some bug. Moreover, let f = id in let (f -> x) = () in x works...

– chi
Nov 14 '18 at 10:01














3














This is quite weird indeed. It might be a bug.



Modifying the original code as follows



where
f x = T.pack (V.toList x)
(f -> t_pre, f -> t_post) = V.splitAt i v


makes GHC ask for FlexibleContexts. After doing that, we get a very strange error:



 Variable not in scope: f :: UV.Vector Char -> t
|
12 | (f -> t_pre, f -> t_post) = V.splitAt i v
| ^
Variable not in scope: f :: UV.Vector Char -> t1
|
12 | (f -> t_pre, f -> t_post) = V.splitAt i v
| ^


This seems like a bug to me. f should be in scope there.



Moving f to global scope:



 ...
where
(f -> t_pre, f -> t_post) = V.splitAt i v

f x = T.pack (V.toList x)


The code now works just fine. It even works if we revert the global f to the pointfree definition.



Using an explicit type annotation, as in



where
f :: UV.Vector Char -> Text
f x = T.pack (V.toList x)
(f -> t_pre, f -> t_post) = V.splitAt i v


produces a puzzling error message



• Variable not in scope: f :: UV.Vector Char -> t
• Perhaps you meant ‘f’ (line 12)


I can't understand what's really going on. In GHCi, both these work fine



> let f = id ; foo (f -> x) = x in foo ()
()
> let bar = foo () where f = id ; foo (f -> x) = x in bar
()


Hence, we can use a local f in view patterns. Still, when the type of f needs some more careful type inference (?), then it can not be used in view patterns. This looks like a bug. At the very least, the error message should be more clear.






share|improve this answer




















  • 1





    Answers in stereo :-P

    – luqui
    Nov 14 '18 at 8:59















3














This is quite weird indeed. It might be a bug.



Modifying the original code as follows



where
f x = T.pack (V.toList x)
(f -> t_pre, f -> t_post) = V.splitAt i v


makes GHC ask for FlexibleContexts. After doing that, we get a very strange error:



 Variable not in scope: f :: UV.Vector Char -> t
|
12 | (f -> t_pre, f -> t_post) = V.splitAt i v
| ^
Variable not in scope: f :: UV.Vector Char -> t1
|
12 | (f -> t_pre, f -> t_post) = V.splitAt i v
| ^


This seems like a bug to me. f should be in scope there.



Moving f to global scope:



 ...
where
(f -> t_pre, f -> t_post) = V.splitAt i v

f x = T.pack (V.toList x)


The code now works just fine. It even works if we revert the global f to the pointfree definition.



Using an explicit type annotation, as in



where
f :: UV.Vector Char -> Text
f x = T.pack (V.toList x)
(f -> t_pre, f -> t_post) = V.splitAt i v


produces a puzzling error message



• Variable not in scope: f :: UV.Vector Char -> t
• Perhaps you meant ‘f’ (line 12)


I can't understand what's really going on. In GHCi, both these work fine



> let f = id ; foo (f -> x) = x in foo ()
()
> let bar = foo () where f = id ; foo (f -> x) = x in bar
()


Hence, we can use a local f in view patterns. Still, when the type of f needs some more careful type inference (?), then it can not be used in view patterns. This looks like a bug. At the very least, the error message should be more clear.






share|improve this answer




















  • 1





    Answers in stereo :-P

    – luqui
    Nov 14 '18 at 8:59













3












3








3







This is quite weird indeed. It might be a bug.



Modifying the original code as follows



where
f x = T.pack (V.toList x)
(f -> t_pre, f -> t_post) = V.splitAt i v


makes GHC ask for FlexibleContexts. After doing that, we get a very strange error:



 Variable not in scope: f :: UV.Vector Char -> t
|
12 | (f -> t_pre, f -> t_post) = V.splitAt i v
| ^
Variable not in scope: f :: UV.Vector Char -> t1
|
12 | (f -> t_pre, f -> t_post) = V.splitAt i v
| ^


This seems like a bug to me. f should be in scope there.



Moving f to global scope:



 ...
where
(f -> t_pre, f -> t_post) = V.splitAt i v

f x = T.pack (V.toList x)


The code now works just fine. It even works if we revert the global f to the pointfree definition.



Using an explicit type annotation, as in



where
f :: UV.Vector Char -> Text
f x = T.pack (V.toList x)
(f -> t_pre, f -> t_post) = V.splitAt i v


produces a puzzling error message



• Variable not in scope: f :: UV.Vector Char -> t
• Perhaps you meant ‘f’ (line 12)


I can't understand what's really going on. In GHCi, both these work fine



> let f = id ; foo (f -> x) = x in foo ()
()
> let bar = foo () where f = id ; foo (f -> x) = x in bar
()


Hence, we can use a local f in view patterns. Still, when the type of f needs some more careful type inference (?), then it can not be used in view patterns. This looks like a bug. At the very least, the error message should be more clear.






share|improve this answer















This is quite weird indeed. It might be a bug.



Modifying the original code as follows



where
f x = T.pack (V.toList x)
(f -> t_pre, f -> t_post) = V.splitAt i v


makes GHC ask for FlexibleContexts. After doing that, we get a very strange error:



 Variable not in scope: f :: UV.Vector Char -> t
|
12 | (f -> t_pre, f -> t_post) = V.splitAt i v
| ^
Variable not in scope: f :: UV.Vector Char -> t1
|
12 | (f -> t_pre, f -> t_post) = V.splitAt i v
| ^


This seems like a bug to me. f should be in scope there.



Moving f to global scope:



 ...
where
(f -> t_pre, f -> t_post) = V.splitAt i v

f x = T.pack (V.toList x)


The code now works just fine. It even works if we revert the global f to the pointfree definition.



Using an explicit type annotation, as in



where
f :: UV.Vector Char -> Text
f x = T.pack (V.toList x)
(f -> t_pre, f -> t_post) = V.splitAt i v


produces a puzzling error message



• Variable not in scope: f :: UV.Vector Char -> t
• Perhaps you meant ‘f’ (line 12)


I can't understand what's really going on. In GHCi, both these work fine



> let f = id ; foo (f -> x) = x in foo ()
()
> let bar = foo () where f = id ; foo (f -> x) = x in bar
()


Hence, we can use a local f in view patterns. Still, when the type of f needs some more careful type inference (?), then it can not be used in view patterns. This looks like a bug. At the very least, the error message should be more clear.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 14 '18 at 19:02

























answered Nov 14 '18 at 8:56









chichi

74.4k284140




74.4k284140







  • 1





    Answers in stereo :-P

    – luqui
    Nov 14 '18 at 8:59












  • 1





    Answers in stereo :-P

    – luqui
    Nov 14 '18 at 8:59







1




1





Answers in stereo :-P

– luqui
Nov 14 '18 at 8:59





Answers in stereo :-P

– luqui
Nov 14 '18 at 8:59

















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53294823%2fviewpatterns-affects-typechecking-in-an-unpredictable-manner%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







這個網誌中的熱門文章

Barbados

How to read a connectionString WITH PROVIDER in .NET Core?

Node.js Script on GitHub Pages or Amazon S3