Let's say I have 100 functions of various simple signatures (start with monomorphic, but would like to make the polymorphic case work too) a -> b (Int -> Int, Int -> String, String -> Double, MyType -> MyOtherType, etc.)
Let's say I show a list of those to the user. The user selects one. I show a list of functions whose parameter is compatible with the selected function's output. The user selects one.
How could I now compose those two functions? The general case is a series of compositions, but this simple case I think covers the problem I'm working with.
I know I could try unsafeCoerce or Data.Dynamic, but I'm trying to see if I can avoid that, and those apparently are restricted to monomorphic types which is causing a problem.
I thought perhaps somehow I could create a data structure of all the functions and what they could be composed with, but I'm not sure about that. And when including polymorphic cases, it seems like it would be impossible.
The question boils down to this: How can I prove to the compiler that this input and that function and what I'm doing with that function's output all line up in a sensible way? There's a couple of answers.
unsafeCoerce
.Data.Dynamic
.a
and b
in your function's a -> b
type. Depending on just how many choices there are for a
and b
, this can be a bit of a drag.As an example of the third option, suppose you have f :: Int -> String
, g :: Double -> Bool
, choice1 :: Int
, choice2 :: Int
, choice3 :: Int
, and choice4 :: Double
. You could write something like this:
main = prompt "f or g" >>= \ans -> case ans of
"f" -> prompt "1, 2, or 3" >>= \ans -> case ans of
"1" -> doSomethingWithString (f choice1)
"2" -> doSomethingWithString (f choice2)
"3" -> doSomethingWithString (f choice3)
"g" -> prompt "4 is your only choice" >>= \ans -> case ans of
"4" -> doSomethingWithBool (g choice4)
This approach can often be cleaned up a lot -- for example, all of the "f" cases could be collapsed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With