
Hello haskell-prime, about limiting variable usage inside a function to some interface - it is possible, although is not pleasant :) {-# OPTIONS_GHC -fglasgow-exts #-} main = do return "xx" >>= ((\x -> print x) :: Show a => a -> IO ()) main2 = do return "xx" >>= (\(x:: (forall a . (Show a) => a)) -> print x) main3 = do (x :: forall a . Show a => a) <- return "xx" print x in this module, only "main" compiles ok -- Best regards, Bulat mailto:bulatz@HotPOP.com

Bulat Ziganshin wrote:
{-# OPTIONS_GHC -fglasgow-exts #-} main = do return "xx" >>= ((\x -> print x) :: Show a => a -> IO ()) main2 = do return "xx" >>= (\(x:: (forall a . (Show a) => a)) -> print x) main3 = do (x :: forall a . Show a => a) <- return "xx" print x
in this module, only "main" compiles ok
The other two need "exists" rather than "forall", which isn't supported by GHC. As written, they say that x can produce a value of any type that's an instance of Show, but the value you're binding to x has type String, which can only produce a value via Show String. -- Ben

Hello Ben, Tuesday, February 07, 2006, 11:21:56 PM, you wrote:
{-# OPTIONS_GHC -fglasgow-exts #-} main = do return "xx" >>= ((\x -> print x) :: Show a => a -> IO ()) main2 = do return "xx" >>= (\(x:: (forall a . (Show a) => a)) -> print x) main3 = do (x :: forall a . Show a => a) <- return "xx" print x
in this module, only "main" compiles ok
BRG> The other two need "exists" rather than "forall", which isn't supported by BRG> GHC. As written, they say that x can produce a value of any type that's an BRG> instance of Show, but the value you're binding to x has type String, which BRG> can only produce a value via Show String. that i want to say is what the first variant allows to define type of 'x' in such way that the only Show-specific operations are allowed, like in the OOP languages when you define something like: widget x := newLabel "text" the second and third variant should do the same, to my mind. of course, you are know all that intrinsics much better. i just can add that some easier variant of declaring 'x' as having only Show interface and mothing more will be great. and as i shown, it's only syntax sugar and don't needs any changes in core language/type system. i'm right? -- Best regards, Bulat mailto:bulatz@HotPOP.com

Bulat Ziganshin
that i want to say is what the first variant allows to define type of 'x' in such way that the only Show-specific operations are allowed,
Why? A class is not a type. Haskell has no non-trivial subtyping. If it's always a string, then it can be treated as a string. Haskell is not Java and can't be coerced to Java without a major redesign of the type system. -- __("< Marcin Kowalczyk \__/ qrczak@knm.org.pl ^^ http://qrnik.knm.org.pl/~qrczak/

Marcin 'Qrczak' Kowalczyk wrote:
Bulat Ziganshin
writes: that i want to say is what the first variant allows to define type of 'x' in such way that the only Show-specific operations are allowed,
Why?
Parametricity, what else? I'd much rather pass my precious String to a function of type [a] -> [a] or Functor a => a Char -> a Char than to a function of type String -> String. Restricting an interface is a very good thing from a program verification standpoint. It's much the same in object-oriented languages, except that the existence of dynamic downcasting kind of spoils things. But then, Haskell has undefined and unsafePerformIO. -- Ben

Ben Rudiak-Gould
that i want to say is what the first variant allows to define type of 'x' in such way that the only Show-specific operations are allowed, Why?
Parametricity, what else? I'd much rather pass my precious String to a function of type [a] -> [a] or Functor a => a Char -> a Char than to a function of type String -> String.
But he is writing the function inline. It doesn't matter whether it's polymorphic when it's ever applied only to a string written in the very same line. -- __("< Marcin Kowalczyk \__/ qrczak@knm.org.pl ^^ http://qrnik.knm.org.pl/~qrczak/

Marcin 'Qrczak' Kowalczyk wrote:
Ben Rudiak-Gould
writes: Parametricity, what else? But he is writing the function inline.
Well, I took it as a stripped-down example. I've often wished for a nonrecursive let in Haskell so that I could write let x = ...x... in ..., and restricting x's interface would be similarly useful. But you could argue that I should break out my pipeline stages into separate functions and compose them, and I suppose you'd probably be right. -- Ben

On Wed, Feb 08, 2006 at 06:01:15PM +0000, Ben Rudiak-Gould wrote:
Well, I took it as a stripped-down example. I've often wished for a nonrecursive let in Haskell so that I could write let x = ...x... in ..., and restricting x's interface would be similarly useful. But you could argue that I should break out my pipeline stages into separate functions and compose them, and I suppose you'd probably be right.
I would argue that the language should discourage variable shadowing, so that shadow warnings can be used to find bugs. Thanks Ian

Hello Ian, Wednesday, February 08, 2006, 9:28:51 PM, you wrote:
nonrecursive let in Haskell so that I could write let x = ...x... in ..., IL> I would argue that the language should discourage variable shadowing, so IL> that shadow warnings can be used to find bugs.
i use such shadowing to change variable meaning in a part of code -- Best regards, Bulat mailto:bulatz@HotPOP.com

Bulat Ziganshin wrote:
main = do return "xx" >>= ((\x -> print x) :: Show a => a -> IO ()) main2 = do return "xx" >>= (\(x:: (forall a . (Show a) => a)) -> print x) main3 = do (x :: forall a . Show a => a) <- return "xx" print x
the second and third variant should do the same, to my mind.
Well, you need to change your mind. :-) Forall is like a function; when you write forall a. Show a => a -> IO () it means something like (a::Type) -> ShowDict a -> a -> IO () In other words, the caller supplies three things: the type a, a dictionary for Show a, and a value of a. But when you write forall a. Show a => a it means something like (a::Type) -> ShowDict a -> a In other words, the caller supplies two things, the type a and a dictionary for Show a, and the callee *returns* a value of a. In this case the callee has to be prepared to produce a value of whatever type the caller requests, and it can't do that if it only has a String. On the other hand exists a. Show a && a means (a::Type, ShowDict a, a) i.e. the callee chooses the type and dictionary as well as the value, which is what you need here. -- Ben
participants (4)
-
Ben Rudiak-Gould
-
Bulat Ziganshin
-
Ian Lynagh
-
Marcin 'Qrczak' Kowalczyk