[Haskell-cafe] ScopedTypeVariables
Occasionally I have to explicitly add a type annotation, either for clarity or to help choose a typeclass instance. Usually top-level type annotations take care of this, but sometimes it's convenient to only annotate a certain value, e.g. one argument of a lambda. I've noticed that while vanilla haskell is happy to allow me to put type annotations on variables where they are used (e.g. '\x - f (x :: T)'), if I put it on the variable where it is bound (e.g. '\(x :: T) - f x'), it wants me to turn on ScopedTypeVariables. I think ScopedTypeVariables is a nice extension and I'm sure it comes from a perfectly respectable family and all, but it feels like annotations on arguments comes in as a side-effect. Would it make sense to split it into a separate extension like TypesOnArguments so I can more accurately express my deviation from haskell2010 orthodoxy? Or is there some deeper tie between scoped type variables and annotations on arguments? Now that I think of it, it seems inconsistent that 'x :: A - B; x a = ...' is valid, but 'x = \(a :: A) - (...) :: B' is not. Doesn't the former desugar to the latter? And what about getting ScopedTypeVariables into haskell prime? As far as I know everyone loves it, or at least no one actually hates it :) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ScopedTypeVariables
This is already a separate extension: PatternSignatures. However, that extension is deprecated for some reason. On Tue, Aug 6, 2013 at 2:46 PM, Evan Laforge qdun...@gmail.com wrote: Occasionally I have to explicitly add a type annotation, either for clarity or to help choose a typeclass instance. Usually top-level type annotations take care of this, but sometimes it's convenient to only annotate a certain value, e.g. one argument of a lambda. I've noticed that while vanilla haskell is happy to allow me to put type annotations on variables where they are used (e.g. '\x - f (x :: T)'), if I put it on the variable where it is bound (e.g. '\(x :: T) - f x'), it wants me to turn on ScopedTypeVariables. I think ScopedTypeVariables is a nice extension and I'm sure it comes from a perfectly respectable family and all, but it feels like annotations on arguments comes in as a side-effect. Would it make sense to split it into a separate extension like TypesOnArguments so I can more accurately express my deviation from haskell2010 orthodoxy? Or is there some deeper tie between scoped type variables and annotations on arguments? Now that I think of it, it seems inconsistent that 'x :: A - B; x a = ...' is valid, but 'x = \(a :: A) - (...) :: B' is not. Doesn't the former desugar to the latter? And what about getting ScopedTypeVariables into haskell prime? As far as I know everyone loves it, or at least no one actually hates it :) ___ 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
Re: [Haskell-cafe] ScopedTypeVariables
Evan Laforge qdun...@gmail.com writes: Would it make sense to split it into a separate extension like TypesOnArguments so I can more accurately express my deviation from haskell2010 orthodoxy? Or is there some deeper tie between scoped type variables and annotations on arguments? I've also wondered why I have to enable ScopedTypeVariables in those cases -- when I'm not turning it on to scope any type variables, but just to make annotations possible in more places. -- John Wiegley FP Complete Haskell tools, training and consulting http://fpcomplete.com johnw on #haskell/irc.freenode.net ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] ScopedTypeVariables in let-bindings (not where-bindings!) and bug 4347
Hi all, I have some problem with ScopedTypeVariables, let and so on, at least in GHC 7. My aim is to be able to supply a polymorphic type signature in let bindings. Confusingly, I find no such example in the blog post about local let generalization [1]. I first met this problem when porting some test-code from Kiselyov, when refusing to convert its let- bindings into where-bindings (which, btw, can't be typed into GHCi). I've also added a comment to the bug report, but it's still quite possible that I'm missing something. == Summary == My starting point today: I wanted to test polymorphic recursion by entering this definition into GHCi: a :: a - a a = a a This is accepted without extra language pragmas but only with the type signature, due to the use of polymorphic recursion for which type inference is undecidable. To type it into GHCi I need to supply a polymorphic type in a let- binding. However, it turns out that Prelude let id2 :: Int - Int = \x - x works but there's no way whatsoever to make the following work: Prelude let (id2 :: forall t. t - t) = \x - x because of bug 4347. But let's start from the beginning. == Walk-through, with various other complaints. == So let's try this: $ ghci -XScopedTypeVariables Prelude let a :: forall b. b - b = a a [...request of enabling -XRank2Types or -XRankNTypes, confusing or BUGGY because the type is rank-1 ...] Prelude :set -XRank2Types Prelude let a :: forall b. b - b = a a interactive:1:31: Couldn't match expected type `forall b. b - b' with actual type `b0 - b0' In the first argument of `a', namely `a' In the expression: a a In a pattern binding: a :: forall b. b - b = a a Uh? That's strange. Seems an instance of bug #4347, but the error message is not yet the same. To get that, let's make an easier example: id. Of course, it needs no type signature, but if one can't give to this an explicit signature, realistic examples are hopeless. So, at the GHCi 7.0.3 prompt, I can't type: Prelude let id2 :: t - t = \x - x GHCi first suggests using -XScopedTypeVariables. Let's try that: Prelude :set -XScopedTypeVariables Prelude let (id2 :: Int - Int) = \x - x This monomorphic function is fine, but the original polymorphic one is not accepted, it complains that t is not in scope - fine, let's add forall: *Main let (id :: forall t. t - t) = \x - x interactive:1:6: Illegal polymorphic or qualified type: forall t. t - t Perhaps you intended to use -XRankNTypes or -XRank2Types In a pattern type signature: forall t. t - t In the pattern: id :: forall t. t - t In a pattern binding: (id :: forall t. t - t) = \ x - x This is already confusing for me - the intended type is rank-1. But let's listen to GHCi again: Prelude :set -XRank2Types Now, the error message is really puzzling: Prelude let (id2 :: forall t. t - t) = \x - x interactive:1:33: Couldn't match expected type `t0 - t1' with actual type `forall t. t - t' The lambda expression `\ x - x' has one argument, but its type `forall t. t - t' has none In the expression: \ x - x In a pattern binding: (id2 :: forall t. t - t) = \ x - x What's up? The documentation never mention let, but it does mention type signatures for patterns [2], and in let a = b in c, a is IIRC a considered a pattern. Still, the lack of examples with let is already confusing. id2 :: forall t. t - t = \x - x How does forall t. t - t have no argument? At worst, it expects a type-argument, in its System F representation . The only implementation problem I see in this code is that unification must see through the forall. I've seen this behavior described [3, 4], but all the problematic examples have been fixed in some way. Here, I see no direct fix. Best regards Paolo G. Giarrusso [1] http://hackage.haskell.org/trac/ghc/blog/LetGeneralisationInGhc7 [2] http://www.haskell.org/ghc/docs/7.0.3/html/users_guide/other-type-extensions.html#pattern-type-sigs [3] http://stackoverflow.com/questions/5885479/weird-error-when-using-scoped-type-variables-and-the-y-combinator-in-haskell [4] http://hackage.haskell.org/trac/ghc/ticket/4347 ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ScopedTypeVariables in let-bindings (not where-bindings!) and bug 4347
On May 21, 2011, at 8:55 AM, Paolo G. Giarrusso wrote: Hi all, I have some problem with ScopedTypeVariables, let and so on, at least in GHC 7. My aim is to be able to supply a polymorphic type signature in let bindings. Confusingly, I find no such example in the blog post about local let generalization [1]. I first met this problem when porting some test-code from Kiselyov, when refusing to convert its let- bindings into where-bindings (which, btw, can't be typed into GHCi). I've also added a comment to the bug report, but it's still quite possible that I'm missing something. You don't need ScopedTypeVariables for this, you can just give type signatures in the let binding: Prelude let id2 :: t - t; id2 = \x - x in (id2 '1', id2 10) ('1',10) -- James ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ScopedTypeVariables in let-bindings (not where-bindings!) and bug 4347
I have no problems in defining those functions: $ ghci GHCi, version 6.12.3: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Loading package ffi-1.0 ... linking ... done. Prelude let id2 :: t - t; id2 = \x - x Prelude let a :: a - a; a = a a Note that I used ';'. This is equivalent to writing let a :: a - a a = a a If I try the syntax you were trying without ScopedTypeVariables, I get Prelude let a :: a - a = a a interactive:1:4: Illegal signature in pattern: a - a Use -XScopedTypeVariables to permit it GHCi thinks that you were trying to define a function by pattern matches and there was a signature inside it, which is a different thing. This is the expected use for such thing: Prelude :s -XScopedTypeVariables Prelude let id2 :: forall t. t - t; id2 (x :: t) = x Cheers, =) -- Felipe. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ScopedTypeVariables in let-bindings (not where-bindings!) and bug 4347
On Saturday 21 May 2011 14:55:54, Paolo G. Giarrusso wrote: However, it turns out that Prelude let id2 :: Int - Int = \x - x works but there's no way whatsoever to make the following work: Prelude let (id2 :: forall t. t - t) = \x - x Works without problems or extensions in the form Prelude let id2 :: t - t; id2 = \x - x Prelude :t id2 id2 :: t - t Also Prelude let a :: t - t; a = a a Prelude :i a a :: t - t -- Defined at interactive:1:18 (of course, using a loops). ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ScopedTypeVariables in let-bindings (not where-bindings!) and bug 4347
On May 21, 3:18 pm, Felipe Almeida Lessa felipe.le...@gmail.com wrote: I have no problems in defining those functions: $ ghci GHCi, version 6.12.3:http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Loading package ffi-1.0 ... linking ... done. Prelude let id2 :: t - t; id2 = \x - x Prelude let a :: a - a; a = a a Note that I used ';'. This is equivalent to writing let a :: a - a a = a a First, thanks to you and everybody for the alternative. But I'm still convinced that the syntax is supposed to work, and you're just workarounding the bug. If I try the syntax you were trying without ScopedTypeVariables, I get Prelude let a :: a - a = a a interactive:1:4: Illegal signature in pattern: a - a Use -XScopedTypeVariables to permit it GHCi thinks that you were trying to define a function by pattern matches and there was a signature inside it, which is a different thing. As I said, I'm convinced that the argument of let is a pattern, on which a signature is allowed, and GHC correctly understands that, so that this declaration work: let (id :: Int - Int) = \x - x See both of: http://www.haskell.org/ghc/docs/7.0.3/html/users_guide/other-type-extensions.html#pattern-type-sigs http://www.haskell.org/onlinereport/decls.html#sect4.4.3.2 This is the expected use for such thing: Prelude :s -XScopedTypeVariables Prelude let id2 :: forall t. t - t; id2 (x :: t) = x Why does then the following declaration work? let (id :: Int - Int) = \x - x To me, this inconsistent behavior is a bug, and surely it is undesirable, because of inconsistency - the programmer needs to have sensible rules, about when let var : type = expr works and when not. Or at least a sensible error message. Moreover, the proposed solution not always works. Neither of these work: let f :: x - x; g :: y - y; (f, g) = (id, id) let f :: x - x; g :: y - y; (f, g) = (f, g) let (f :: forall a. a - a, g :: forall a. a - a) = (f, g) let (f :: forall a. a - a, g :: forall a. a - a) = (id, id) If you wonder why one , the tuple might be returned by another function. Additionally, I'd like to debug documentation. If, when looking up docs, I can't find a solution, either I miss something or the documentation is incomplete. In the second case, I'd like to propose fixes. I've just verified that the Haskell Report allows the syntax you describe, but of course it doesn't specify the behavior of the extension. But for instance I've not found type declaration for let bindings in Real World Haskell (a Gentle introduction to Haskell mentions them in one point of the document, without examples). Cheers, Paolo G. Giarrusso ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ScopedTypeVariables in let-bindings (not where-bindings!) and bug 4347
On Sat, May 21, 2011 at 10:17, Paolo G. Giarrusso p.giarru...@gmail.comwrote: First, thanks to you and everybody for the alternative. But I'm still convinced that the syntax is supposed to work, and you're just workarounding the bug. Hm, I think we have differing expectations; the syntax everyone presented is the one that is normally used for such things in ghci, and while perhaps the one you tried is supposed to work, it's a bit unusual and therefore probably not very well tested. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ScopedTypeVariables in let-bindings (not where-bindings!) and bug 4347
On Saturday 21 May 2011 16:17:53, Paolo G. Giarrusso wrote: Moreover, the proposed solution not always works. Neither of these work: let f :: x - x; g :: y - y; (f, g) = (id, id) let f :: x - x; g :: y - y; (f, g) = (f, g) Requires -XNoMonoPatBinds ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ScopedTypeVariables in let-bindings (not where-bindings!) and bug 4347
On Sat, May 21, 2011 at 11:17 AM, Paolo G. Giarrusso p.giarru...@gmail.com wrote: As I said, I'm convinced that the argument of let is a pattern, on which a signature is allowed, and GHC correctly understands that, so that this declaration work: let (id :: Int - Int) = \x - x See both of: http://www.haskell.org/ghc/docs/7.0.3/html/users_guide/other-type-extensions.html#pattern-type-sigs http://www.haskell.org/onlinereport/decls.html#sect4.4.3.2 Actually, it doesn't work ;-) Prelude let (id2 :: Int - Int) = \x - x interactive:1:5: Illegal signature in pattern: Int - Int Use -XScopedTypeVariables to permit it Patterns can't have types in Haskell 98 [1]. So you actually need to see what the ScopedTypeVariables say about it [2, 3]. The GHC user guide [3] is pretty clear saying that pattern type signatures can't bring new type variables into scope like you want. [1] http://www.haskell.org/onlinereport/exps.html#sect3.17.1 [2] http://hackage.haskell.org/trac/haskell-prime/wiki/ScopedTypeVariables [3] http://www.haskell.org/ghc/docs/7.0-latest/html/users_guide/other-type-extensions.html#pattern-type-sigs To me, this inconsistent behavior is a bug, and surely it is undesirable, because of inconsistency - the programmer needs to have sensible rules, about when let var : type = expr works and when not. Or at least a sensible error message. The bug seems to be with the error message. But the behaviour looks like what was expressed by the docs. I think you could file a bug about it. Moreover, the proposed solution not always works. Neither of these work: let f :: x - x; g :: y - y; (f, g) = (id, id) let f :: x - x; g :: y - y; (f, g) = (f, g) let (f :: forall a. a - a, g :: forall a. a - a) = (f, g) let (f :: forall a. a - a, g :: forall a. a - a) = (id, id) If you wonder why one , the tuple might be returned by another function. Prelude let f :: x - x; g :: y - y; (f, g) = (id, id) interactive:1:40: Couldn't match expected type `forall x. x - x' against inferred type `a - a' In the expression: id In the expression: (id, id) In a pattern binding: (f, g) = (id, id) Prelude :s -XNoMonoPatBinds Prelude let f :: x - x; g :: y - y; (f, g) = (id, id) See [4]. [4] http://hackage.haskell.org/trac/haskell-prime/wiki/MonomorphicPatternBindings Cheers! =) -- Felipe. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ScopedTypeVariables in let-bindings (not where-bindings!) and bug 4347
On Sat, May 21, 2011 at 16:27, Brandon Allbery allber...@gmail.com wrote: On Sat, May 21, 2011 at 10:17, Paolo G. Giarrusso p.giarru...@gmail.com wrote: First, thanks to you and everybody for the alternative. But I'm still convinced that the syntax is supposed to work, and you're just workarounding the bug. Hm, I think we have differing expectations; the syntax everyone presented is the one that is normally used for such things in ghci, and while perhaps the one you tried is supposed to work, it's a bit unusual and therefore probably not very well tested. Yes, it was my guess as well - and for some reason I missed the usual syntax. A sincere question about the usual syntax: where do you learn it? It's needed seldom enough that I don't see it often in tutorials. And Googling for let type signature haskell leads me to the Haskell report or to ScopedTypeVariables. Cheers, -- Paolo Giarrusso - Ph.D. Student http://www.informatik.uni-marburg.de/~pgiarrusso/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ScopedTypeVariables in let-bindings (not where-bindings!) and bug 4347
On Saturday 21 May 2011 16:17:53, Paolo G. Giarrusso wrote: As I said, I'm convinced that the argument of let is a pattern, on which a signature is allowed, and GHC correctly understands that, so that this declaration work: let (id :: Int - Int) = \x - x I don't think that Prelude let a :: a - a = a a (or even Prelude let id2 :: t - t = \x - x ) is supposed to work: The pattern in a pattern binding may only mention type variables that are already in scope. Both are pattern bindings and the mentioned type variable is not in scope. See both of: http://www.haskell.org/ghc/docs/7.0.3/html/users_guide/other-type-extens ions.html#pattern-type-sigs http://www.haskell.org/onlinereport/decls.html#sect4.4.3.2 This is the expected use for such thing: Prelude :s -XScopedTypeVariables Prelude let id2 :: forall t. t - t; id2 (x :: t) = x Why does then the following declaration work? let (id :: Int - Int) = \x - x Because it doesn't mention any type variable. To me, this inconsistent behavior is a bug, and surely it is undesirable, because of inconsistency - the programmer needs to have sensible rules, about when let var : type = expr works and when not. Or at least a sensible error message. The error message definitely deserves improvement. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ScopedTypeVariables in let-bindings (not where-bindings!) and bug 4347
On Sat, May 21, 2011 at 16:46, Felipe Almeida Lessa felipe.le...@gmail.com wrote: On Sat, May 21, 2011 at 11:17 AM, Paolo G. Giarrusso p.giarru...@gmail.com wrote: As I said, I'm convinced that the argument of let is a pattern, on which a signature is allowed, and GHC correctly understands that, so that this declaration work: let (id :: Int - Int) = \x - x See both of: http://www.haskell.org/ghc/docs/7.0.3/html/users_guide/other-type-extensions.html#pattern-type-sigs http://www.haskell.org/onlinereport/decls.html#sect4.4.3.2 Actually, it doesn't work ;-) Prelude let (id2 :: Int - Int) = \x - x interactive:1:5: Illegal signature in pattern: Int - Int Use -XScopedTypeVariables to permit it I tried that with -XScopedTypeVariables enabled, I didn't say it because I thought it was implicit, and for conciseness: $ ghci Prelude :set -XScopedTypeVariables Prelude let (id :: Int - Int) = \x - x Prelude id 1 1 Patterns can't have types in Haskell 98 [1]. So you actually need to see what the ScopedTypeVariables say about it [2, 3]. The GHC user guide [3] is pretty clear saying that pattern type signatures can't bring new type variables into scope like you want. Well, the examples don't use forall. The guide states that: Unlike expression and declaration type signatures, pattern type signatures are not implicitly generalised. And I don't want implicit generalization. Adding nor can they be explicitly generalized would already be unambiguous, and extra examples would be nice. The rest of the text might or might not forbid to explicitly introduce type variables with forall, but it doesn't say that. I agree that your interpretation is also plausible, but then I'd like the text to be clarified (and the error message to be fixed as you suggest). [1] http://www.haskell.org/onlinereport/exps.html#sect3.17.1 [2] http://hackage.haskell.org/trac/haskell-prime/wiki/ScopedTypeVariables [3] http://www.haskell.org/ghc/docs/7.0-latest/html/users_guide/other-type-extensions.html#pattern-type-sigs To me, this inconsistent behavior is a bug, and surely it is undesirable, because of inconsistency - the programmer needs to have sensible rules, about when let var : type = expr works and when not. Or at least a sensible error message. The bug seems to be with the error message. But the behaviour looks like what was expressed by the docs. I think you could file a bug about it. Moreover, the proposed solution not always works. Neither of these work: let f :: x - x; g :: y - y; (f, g) = (id, id) let f :: x - x; g :: y - y; (f, g) = (f, g) let (f :: forall a. a - a, g :: forall a. a - a) = (f, g) let (f :: forall a. a - a, g :: forall a. a - a) = (id, id) If you wonder why one , the tuple might be returned by another function. Prelude let f :: x - x; g :: y - y; (f, g) = (id, id) interactive:1:40: Couldn't match expected type `forall x. x - x' against inferred type `a - a' In the expression: id In the expression: (id, id) In a pattern binding: (f, g) = (id, id) Prelude :s -XNoMonoPatBinds Prelude let f :: x - x; g :: y - y; (f, g) = (id, id) See [4]. [4] http://hackage.haskell.org/trac/haskell-prime/wiki/MonomorphicPatternBindings I see, thanks. This applies even to explicit foralls, which are ignored instead of giving an error. So even the following line only works with -XNoMonoPatBinds, and I get no complaints about the foralls: let f :: forall x. x - x; g :: forall y. y - y; (f, g) = (id, id) I guess, I should report a bug about that. Cheers, -- Paolo Giarrusso - Ph.D. Student http://www.informatik.uni-marburg.de/~pgiarrusso/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ScopedTypeVariables in let-bindings (not where-bindings!) and bug 4347
On Sat, May 21, 2011 at 10:49, Paolo Giarrusso p.giarru...@gmail.comwrote: On Sat, May 21, 2011 at 16:27, Brandon Allbery allber...@gmail.com wrote: On Sat, May 21, 2011 at 10:17, Paolo G. Giarrusso p.giarru...@gmail.com wrote: First, thanks to you and everybody for the alternative. But I'm still convinced that the syntax is supposed to work, and you're just workarounding the bug. Hm, I think we have differing expectations; the syntax everyone presented is the one that is normally used for such things in ghci, and while perhaps the one you tried is supposed to work, it's a bit unusual and therefore probably not very well tested. Yes, it was my guess as well - and for some reason I missed the usual syntax. A sincere question about the usual syntax: where do you learn it? It's It's just the desugaring of layout, with the braces being optional because it's all on one line. Since you can't use layout in ghci, you have to manually convert. It is perhaps not entirely obvious (I was a bit surprised when, as a complete Haskell newbie, I decided to try it and it worked) that you can specify types in both let and where clauses in the same way you do at the top level: let a :: a - a a = a a where b :: b - b b = b b which in its non-layout version is let { a :: a - a; a = a a } where { b :: b - b; b = b b } (using the braces here because it's a bit ambiguous; I think H'2010 fixed that though) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ScopedTypeVariables in let-bindings (not where-bindings!) and bug 4347
On Sat, May 21, 2011 at 17:13, Brandon Allbery allber...@gmail.com wrote: On Sat, May 21, 2011 at 10:49, Paolo Giarrusso p.giarru...@gmail.com wrote: On Sat, May 21, 2011 at 16:27, Brandon Allbery allber...@gmail.com wrote: On Sat, May 21, 2011 at 10:17, Paolo G. Giarrusso p.giarru...@gmail.com wrote: First, thanks to you and everybody for the alternative. But I'm still convinced that the syntax is supposed to work, and you're just workarounding the bug. Hm, I think we have differing expectations; the syntax everyone presented is the one that is normally used for such things in ghci, and while perhaps the one you tried is supposed to work, it's a bit unusual and therefore probably not very well tested. Yes, it was my guess as well - and for some reason I missed the usual syntax. A sincere question about the usual syntax: where do you learn it? It's It's just the desugaring of layout, with the braces being optional because it's all on one line. Since you can't use layout in ghci, you have to manually convert. It is perhaps not entirely obvious (I was a bit surprised when, as a complete Haskell newbie, I decided to try it and it worked) that you can specify types in both let and where clauses in the same way you do at the top level: Exactly. I've seen examples with where, but only today I've seen this example with let. Luckily I was aware of layout desugaring - that's explained in most tutorials I know. let a :: a - a a = a a Anyway, thanks. I hope some more advanced tutorial, some day, will also show such examples. -- Paolo Giarrusso - Ph.D. Student http://www.informatik.uni-marburg.de/~pgiarrusso/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe