
I have an almost finished Haskell program and I discovered that I needed to change the type of one record field. The problem is that the new type is polymorphic. Being new to Haskell, I simply changed: data MyStruct = MyStruct {myField :: myType} to data MyStruct = MyStruct {myField :: MyTypeClass a => a} and then ended up in a maze of compiler messages about Rank N types and "Inferred type is less polymorphic than expected". Upon Googling for this issue, I have discovered that Haskell records do not support polymorphic types and that there is a large literature about options to fix this. Although the literature is interesting, what I am looking for right now is a simple fix. I really don't want to have to rewrite all the many type and value references to MyStruct in my code. Is there a way to redefine the definition of MyStruct without changing any of my other code? If I have to change the way myField is accessed, I can handle that. What I don't really want to do is change the type signature of functions that take MyStruct parameters (of which there are many). Is this possible? What is the simplest way to do this? Kevin

How about:
data MyStruct = forall a. MyTypeClass a => MyStruct {myField :: a}
I haven't actually run that through the compiler, but it should work.
For a "real life" example of this approach, look at SomeException[1].
Michael
[1] http://www.haskell.org/ghc/docs/6.12.2/html/libraries/base-4.2.0.1/Control-E...
On Sun, Sep 26, 2010 at 12:51 PM, Kevin Jardine
I have an almost finished Haskell program and I discovered that I needed to change the type of one record field.
The problem is that the new type is polymorphic.
Being new to Haskell, I simply changed:
data MyStruct = MyStruct {myField :: myType}
to
data MyStruct = MyStruct {myField :: MyTypeClass a => a}
and then ended up in a maze of compiler messages about Rank N types and "Inferred type is less polymorphic than expected".
Upon Googling for this issue, I have discovered that Haskell records do not support polymorphic types and that there is a large literature about options to fix this.
Although the literature is interesting, what I am looking for right now is a simple fix.
I really don't want to have to rewrite all the many type and value references to MyStruct in my code.
Is there a way to redefine the definition of MyStruct without changing any of my other code?
If I have to change the way myField is accessed, I can handle that. What I don't really want to do is change the type signature of functions that take MyStruct parameters (of which there are many).
Is this possible? What is the simplest way to do this?
Kevin _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

OK, thanks for this advice.
The type definition compiles, but when I try to actually access
myField, the compiler says:
Cannot use record selector `myField' as a function due to escaped type
variables
Probable fix: use pattern-matching syntax instead
So I took the hint and wrote a new pattern matching accessor function:
getMyField (MyStruct value) = value
and I get:
Inferred type is less polymorphic than expected
Quantified type variable `a' escapes
When checking an existential match that binds
value :: a
Any further suggestions?
On Sep 26, 1:09 pm, Daniel Fischer
On Sunday 26 September 2010 12:53:46, Michael Snoyman wrote:
data MyStruct = forall a. MyTypeClass a => MyStruct {myField :: a}
Note that that requires {-# LANGUAGE ExistentialQuantification #-} _______________________________________________ Haskell-Cafe mailing list Haskell-C...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe

OK, I have a solution. Ugly, but it compiles.
MyStruct actually has quite a few fields but I only need to access the
polymorphic field 4 times.
So for the functions that needed that I wrote:
f myS@(MyStruct value _ _ _ )
and then could use value. I could then use the usual record accessors
on myS to get the other (non-polymorphic) data.
I guess that is what GHC was hinting at when it suggested pattern
matching.
That is, pattern matching could extract a value that no functions are
apparently allowed to touch.
All head spinning to me.
Thanks for the (as always) fast and useful advice!
Kevin
On Sep 26, 2:00 pm, Kevin Jardine
OK, thanks for this advice.
The type definition compiles, but when I try to actually access myField, the compiler says:
Cannot use record selector `myField' as a function due to escaped type variables Probable fix: use pattern-matching syntax instead
So I took the hint and wrote a new pattern matching accessor function:
getMyField (MyStruct value) = value
and I get:
Inferred type is less polymorphic than expected Quantified type variable `a' escapes When checking an existential match that binds value :: a
Any further suggestions?
On Sep 26, 1:09 pm, Daniel Fischer
wrote:> On Sunday 26 September 2010 12:53:46, Michael Snoyman wrote: data MyStruct = forall a. MyTypeClass a => MyStruct {myField :: a}
Note that that requires {-# LANGUAGE ExistentialQuantification #-} _______________________________________________ Haskell-Cafe mailing list Haskell-C...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-C...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe

How about
f myS@(MyStruct { myField = value })
?
On Sun, Sep 26, 2010 at 2:14 PM, Kevin Jardine
OK, I have a solution. Ugly, but it compiles.
MyStruct actually has quite a few fields but I only need to access the polymorphic field 4 times.
So for the functions that needed that I wrote:
f myS@(MyStruct value _ _ _ )
and then could use value. I could then use the usual record accessors on myS to get the other (non-polymorphic) data.
I guess that is what GHC was hinting at when it suggested pattern matching.
That is, pattern matching could extract a value that no functions are apparently allowed to touch.
All head spinning to me.
Thanks for the (as always) fast and useful advice!
Kevin
On Sep 26, 2:00 pm, Kevin Jardine
wrote: OK, thanks for this advice.
The type definition compiles, but when I try to actually access myField, the compiler says:
Cannot use record selector `myField' as a function due to escaped type variables Probable fix: use pattern-matching syntax instead
So I took the hint and wrote a new pattern matching accessor function:
getMyField (MyStruct value) = value
and I get:
Inferred type is less polymorphic than expected Quantified type variable `a' escapes When checking an existential match that binds value :: a
Any further suggestions?
On Sep 26, 1:09 pm, Daniel Fischer
wrote:> On Sunday 26 September 2010 12:53:46, Michael Snoyman wrote: data MyStruct = forall a. MyTypeClass a => MyStruct {myField :: a}
Note that that requires {-# LANGUAGE ExistentialQuantification #-} _______________________________________________ Haskell-Cafe mailing list Haskell-C...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-C...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe
Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Hi Michael,
Yes, that does compile!
Much less ugly and does not expose the internal bits of MyStruct.
Thanks.
Kevin
On Sep 26, 2:26 pm, Michael Snoyman
How about
f myS@(MyStruct { myField = value })
?
On Sun, Sep 26, 2010 at 2:14 PM, Kevin Jardine
wrote: OK, I have a solution. Ugly, but it compiles.
MyStruct actually has quite a few fields but I only need to access the polymorphic field 4 times.
So for the functions that needed that I wrote:
f myS@(MyStruct value _ _ _ )
and then could use value. I could then use the usual record accessors on myS to get the other (non-polymorphic) data.
I guess that is what GHC was hinting at when it suggested pattern matching.
That is, pattern matching could extract a value that no functions are apparently allowed to touch.
All head spinning to me.
Thanks for the (as always) fast and useful advice!
Kevin
On Sep 26, 2:00 pm, Kevin Jardine
wrote: OK, thanks for this advice.
The type definition compiles, but when I try to actually access myField, the compiler says:
Cannot use record selector `myField' as a function due to escaped type variables Probable fix: use pattern-matching syntax instead
So I took the hint and wrote a new pattern matching accessor function:
getMyField (MyStruct value) = value
and I get:
Inferred type is less polymorphic than expected Quantified type variable `a' escapes When checking an existential match that binds value :: a
Any further suggestions?
On Sep 26, 1:09 pm, Daniel Fischer
wrote:> On Sunday 26 September 2010 12:53:46, Michael Snoyman wrote: data MyStruct = forall a. MyTypeClass a => MyStruct {myField :: a}
Note that that requires {-# LANGUAGE ExistentialQuantification #-} _______________________________________________ Haskell-Cafe mailing list Haskell-C...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-C...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe
Haskell-Cafe mailing list Haskell-C...@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-C...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe

On Sunday 26 September 2010 14:00:38, Kevin Jardine wrote:
OK, thanks for this advice.
The type definition compiles, but when I try to actually access myField, the compiler says:
Cannot use record selector `myField' as a function due to escaped type variables Probable fix: use pattern-matching syntax instead
So I took the hint and wrote a new pattern matching accessor function:
getMyField (MyStruct value) = value
and I get:
Inferred type is less polymorphic than expected Quantified type variable `a' escapes When checking an existential match that binds value :: a
Any further suggestions?
Ah, yes, forgot about that. As GHC says, using getMyValue would let the quantified type variable escape, the type would be getMyValue :: exists a. MyStruct -> a (not allowed in Haskell). You can only use myField per pattern matching foo :: MyStruct -> whatever foo (MyStruct field) = methodOfMyTypeClass field
On Sep 26, 1:09 pm, Daniel Fischer
wrote: On Sunday 26 September 2010 12:53:46, Michael Snoyman wrote:
data MyStruct = forall a. MyTypeClass a => MyStruct {myField :: a}
Note that that requires {-# LANGUAGE ExistentialQuantification #-}
participants (3)
-
Daniel Fischer
-
Kevin Jardine
-
Michael Snoyman