Why doesn't extractEither
typecheck?
data MyEither a b = MyLeft a | MyRight b
deriving (Read, Show)
extractEither :: MyEither a b -> c
extractEither (MyLeft p) = p
The compiler shows:
Couldn't match type `a' with `c'
`a' is a rigid type variable bound by
the type signature for extractEither :: MyEither a b -> c
at /Users/tongmuchenxuan/playground/test.hs:5:1
`c' is a rigid type variable bound by
the type signature for extractEither :: MyEither a b -> c
at /Users/tongmuchenxuan/playground/test.hs:5:1
In the expression: p
In an equation for `extractEither': extractEither (MyLeft p) = p
Isn't `c' general enough to catch any type?
No. c
is any type the caller could wish the function to return, i.e. for a function f :: a -> c
it would always need to be possible to write f x + 1 :: Int
as well as putStr $ f x
as well as main = f x
. Which your function does of course not permit.
What you want is returning a dynamic type. Haskell deliberately does not permit this as easily as some other languages do, because it obviously can lead to runtime errors easily when the returned type is something unexpected. There are various ways to do it, but which is the right one depends on what you actually want this for. Could you give some context? It's likely that the best solution to your problem would not use dynamic types, but something more Haskell-idiomatic.
Perhaps what you want is simply
extractEither :: MyEither a a -> a
extractEither (MyLeft p) = p
extractEither (MyRight p) = p
which requires that the types on both "sides" are the same.
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