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 6941529
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 27, 20262026-05-27T12:53:51+00:00 2026-05-27T12:53:51+00:00

So say I have a class: class C a where reduce :: a ->

  • 0

So say I have a class:

class C a where
  reduce :: a -> Int

Now I want to pack it up in a data type:

data Signal = forall a. (C a) => Signal [(Double, a)]

Thanks to the existential quantification, I can call C methods on Signals, but Signals don’t expose a type parameter:

reduceSig :: Signal -> [(Double, Int)]
reduceSig (Signal sig) = map (second reduce) sig

Now since C has a number of methods my natural next step is to pull out the ‘reduce’ function so I can substitute any method:

mapsig :: (C a) => (a -> a) -> Signal -> Signal
mapsig f (Signal sig) = Signal (map (second f) sig)

Type error! Could not deduce (a1 ~ a). On further thought, I think what it’s saying is that ‘f’ is a function on some instance of C, but I can’t guarantee it’s the same instance of C as in the Signals, because the type parameters are concealed! I wanted it, I got it.

So does this mean it’s impossible to generalize reduceSig? I can live with this, but I’m so used to freely factoring out functions in haskell it feels strange to be obliged to write the boilerplate. On the other hand, I can’t think of any way to express that a type is equal to the type inside of Signal, short of giving Signal a type parameter.

  • 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-27T12:53:52+00:00Added an answer on May 27, 2026 at 12:53 pm

    What you need to express is that f, like reduce used in reduceSig, can be applied to any type that is an instance of C, as opposed to the current type, where f works on a single type that is an instance of C. This can be done like so:

    mapsig :: (forall a. (C a) => a -> a) -> Signal -> Signal
    mapsig f (Signal sig) = Signal (map (second f) sig)
    

    You’ll need the RankNTypes extension, as you often do when using existential types; note that the implementation of mapsig is the same, the type has just been generalised.

    Basically, with this type, mapsig gets to decide which a the function is called on; with your previous type, the caller of mapsig gets to decide that, which doesn’t work, because only mapsig knows the correct a, i.e. the one inside the Signal.

    However, mapsig reduce does not work, for the obvious reason that reduce :: (C a) => a -> Int, and you don’t know that a is Int! You need to give mapsig a more general type (with the same implementation):

    mapsig :: (C b) => (forall a. (C a) => a -> b) -> Signal -> Signal
    

    i.e., f is a function taking any type that is an instance of C, and producing a type that is an instance of C (that type is fixed at the time of the mapsig call and chosen by the caller; i.e. while the value mapsig f can be called on any Signal, it will always produce a Signal with the same a as a result (not that you can inspect this from outside).)

    Existentials and rank-N types are very tricky indeed, so this might take a bit of time to digest. 🙂


    As an addendum, it’s worth pointing out that if all the functions in C look like a -> r for some r, then you would be better off creating a record instead, i.e. turning

    class C a where
      reduce :: a -> Int
      foo :: a -> (String, Double)
      bar :: a -> ByteString -> Magic
    
    data Signal = forall a. (C a) => Signal [(Double, a)]
    
    mapsig :: (C b) => (forall a. (C a) => a -> b) -> Signal -> Signal
    

    into

    data C = C
      { reduce :: Int
      , foo :: (String, Double)
      , bar :: ByteString -> Magic
      }
    
    data Signal = Signal [(Double, C)]
    
    mapsig :: (C -> C) -> Signal -> Signal
    

    These two Signal types are actually equivalent! The benefits of the former solution only appear when you have other data types that use C without existentially quantifying it, so that you can have code that uses special knowledge and operations of the specific instance of C it’s using. If your primary use-cases of this class are through existential quantification, you probably don’t want it in the first place. But I don’t know what your program looks like 🙂

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

Sidebar

Related Questions

say I have: class Test { public static int Hello = 5; } This
Say you have a class declaration, e.g.: class MyClass { int myInt=7; int myOtherInt;
Say I have a class definition: class CustomClass { int member; }; Why is
Say I have class myClass in file myClass.py and I want to be able
Lets say I have class Person { public Person(int age, string name) { Age
Say I have: class DecisionTree(private val instances: Array[Instance]){ and I want to calculate another
Say I have class A with class A { final String foo() { //
Say we have: class Base { virtual void f() {g();}; virtual void g(){//Do some
Say I have: class Vector3 { float x, y, z; ... bunch of cuntions
Say I have a class named Frog, it looks like: public class Frog {

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.