Is there any way in Haskell to forcibly force a polymorphic challenge?

I have a list of values โ€‹โ€‹(or functions) of any type. I have another list of functions of any type. The user at runtime selects one from the first list and the other from the second list. I have a mechanism for ensuring the compatibility of two elements (the value or output from the first is compatible with the input of the second).

I need to somehow call a function with a value (or compose a function). If the second function has specific types, unsafeCoerce works fine. But if it has the form:

polyFunc :: MyTypeclass a => a -> IO () polyFunc x = print . show . typeclassFunc x 

Then unsafeCoerce does not work, because it cannot solve a specific type.

Is there a way to do what I'm trying to do?

Here is an example of how the lists look. However ... I am not limited to this, if there is any other way to present them that will solve the problem, I would like to know. It is important to consider the following: the list may change at run time, so at compile time I do not know all the possible types that can be involved.

 data Wrapper = forall a. Wrapper a firstList :: [Wrapper] firstList = [Wrapper "blue", Wrapper 5, Wrapper valueOfMyTypeclass] data OtherWrapper = forall a. Wrapper (a -> IO ()) secondList :: [OtherWrapper] secondList = [OtherWrapper print, OtherWrapper polyFunc] 

Note. As for why I want to do such a crazy thing: I generate code and test it with a hint. But this happens at runtime. The problem is that the hint is slow, actually doing things, and high performance is crucial. Also, at least in some cases, I donโ€™t want to generate code and run it through ghc at runtime (although we did it too). So ... Iโ€™m trying to find somewhere in the middle: dynamically connecting things without creating code or compiling, but starting it at compiled speed instead of interpreted.

+4
source share
2 answers

Edit : Well, now that I see that a little more is happening, here is a very general approach - don't use polymorphic functions at all! Use functions like Dynamic -> IO () instead! Then they can directly use a typecase type dispatcher to select which monomorphic function to call, i.e. Just enable TypeRep. You need to code this dispatch directly for each polymorphic function that you wrap. However, you can automate this with some kind of Haskell template if it gets a bit of a hassle.

Essentially, instead of overloading the Haskell polymorphism, just as Dynamic embeds a dynamically typed language in a statically typed language, you now extend this to embed dynamic polymorphism in a statically typed language.

-

Old answer: more code would be helpful. But as far as I can tell, this is a reading / show issue. That is, you have a function that produces a polymorphic result and a function that accepts a polymorphic input. The problem is that you need to choose what the intermediate value is so that it satisfies both constraints. If you have a mechanism for this, then the usual tricks will work, making sure you satisfy this open question, about whom the compiler cannot know the answer.

+3
source

I'm not sure I fully understand your question. But since you have a value and a function that have compatible types, you can combine them into one value. Then the compiler can prove that the types match.

 {-# LANGUAGE ExistentialQuantification #-} data Vault = forall a . Vault (a -> IO ()) a runVault :: Vault -> IO () runVault (Vault fx) = f xrun 
+1
source

All Articles