Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6682839
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 26, 20262026-05-26T04:45:08+00:00 2026-05-26T04:45:08+00:00

In (very) modern GHC’s, I can write this: {-# LANGUAGE TypeFamilies #-} — consider

  • 0

In (very) modern GHC’s, I can write this:

{-# LANGUAGE TypeFamilies #-}

-- consider this part "library" code, changeable at will
data Container a = Container
data Element
class Foo a where foo :: a -> Int
instance Element ~ a => Foo (Container a) where foo _ = 0

-- consider this part "client" code; bonus points if it can remain exactly as is
main = print (foo Container)

Salient points:

  1. The client code did not require any additional type signatures.
  2. Container, which is a polymorphic value (of type Container a), was correctly monomorphed to Container Element.
  3. No newtype wrappers were required in the client code.
  4. It is probably not possible to declare another instance of Foo whose outermost type constructor is Container. This is not a property I care about preserving in the following discussion.

Can this be done in a more backwards-compatible way? My first attempt looked like this:

{-# LANGUAGE FlexibleInstances #-}

data Container a = Container
data Element
class Foo a where foo :: a -> Int
instance Foo (Container Element) where foo _ = 0

main = print (foo Container)

…which gives an error:

test.hs:8:15:
    No instance for (Foo (Container a0))
      arising from a use of `foo'
    Possible fix: add an instance declaration for (Foo (Container a0))
    In the first argument of `print', namely `(foo Container)'
    In the expression: print (foo Container)
    In an equation for `main': main = print (foo Container)

I realized that this error probably arises because the instance doesn’t use a type variable as the argument to Container, so I also tried:

{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, UndecidableInstances #-}

data Container a = Container
data Element
class Foo a where foo :: a -> Int
instance Convertible a Element => Foo (Container a) where foo _ = 0
class Convertible a b where
    -- convert is not necessary in this tiny example, but it would
    -- be necessary in my not-so-tiny use case
    convert :: Container a -> Container b
instance Convertible a a where
    convert = id

main = print (foo Container)

But this just pushes the problem to the Convertible type class:

test.hs:14:19:
    No instance for (Convertible a0 Element)
      arising from a use of `foo'
    Possible fix:
      add an instance declaration for (Convertible a0 Element)
    In the first argument of `print', namely `(foo Container)'
    In the expression: print (foo Container)
    In an equation for `main': main = print (foo Container)

A similar error arises from writing an instance for Convertible Element Element instead of Convertible a a. My last-ditch attempt was to specialize even further:

data Container a = Container
data Element
class Foo a where foo :: a -> Int
instance IsElement a => Foo (Container a) where foo _ = 0
class IsElement a where
    convert :: a -> Element
instance IsElement Element where
    convert = id

main = print (foo Container)

…which has the notable benefit of being H98, but the notable downside of still not quite working:

test.hs:10:19:
    Ambiguous type variable `a0' in the constraint:
      (IsElement a0) arising from a use of `foo'
    Probable fix: add a type signature that fixes these type variable(s)
    In the first argument of `print', namely `(foo Container)'
    In the expression: print (foo Container)
    In an equation for `main': main = print (foo Container)

So, the question is this: is there some similar implementation that achieves properties 1, 2, and 3 above, yet does not require the type equality operator?

edit I thought rank-2 types might help:

{-# LANGUAGE FlexibleInstances, RankNTypes #-}

data Container a = Container
data Element
class Foo a where foo :: a -> Int
instance Foo (forall a. Container a) where foo _ = 0

main = print (foo Container)

…but alas, still no dice:

test.hs:6:14:
    Illegal polymorphic or qualified type: forall a. Container a
    In the instance declaration for `Foo (forall a. Container a)'
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-26T04:45:08+00:00Added an answer on May 26, 2026 at 4:45 am

    I don’t understand what you’re trying to do here. In particular, why do you care that Container is polymorphic when you only want the client to work with Container Element?

    That said, how about using a different kind for the type class?

    data Container a = Container
    data Element
    
    class Foo a where foo :: a x -> Int
    
    instance Foo Container where foo _ = 0
    

    Now it truly doesn’t matter which type Container is instantiated to.

    If this doesn’t work, I suspect the answer is “no, you can’t do precisely what you want.” Although you could export container = Container :: Container Element and have client code use that instead of Container.

    Edit: given the full context, and that rank-2 types aren’t possible either, I am reasonably certain that there isn’t a solution given the problem constraints. The best workaround I can think of is creating a new function xcast :: XConfig a -> XConfig Layout. This would allow you to write instance Binding (XConfig a -> Foo).

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Consider this simple python code, which demonstrates a very simple version control design for
Very simply put, I have the following code snippet: FILE* test = fopen(C:\\core.u, w);
Very often when working on an ASP.NET web site, the options View Code and
Very basic question: how do I write a short literal in C++? I know
Very simply, what is tail-call optimization? More specifically, what are some small code snippets
Very odd problem as this is working perfectly on our old Classic ASP site.
Very similar to this question , except for Java. What is the recommended way
I am very interested in how modern Windows software is written in C++ nowadays.
I've been developing an app specifically for modern browsers and have made very heavy
Now i know that this one is actually not a very technical question but

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.