Reputation: 11803
Is it possible to use case
expression between two unrelated types in Haskell, like in this example (not working) code:
data A = A
data B = B
f x = case x of
A -> 1
B -> 2
main = do
print $ test A
return ()
I know I can use Either
here, but this code is not meant to be used - I want to deeply learn the Haskell type system and see what could be done.
Upvotes: 3
Views: 129
Reputation: 1308
Rather than writing your own type class for f, you could use the Typeable class which has some support by ghc. You don't need to use Dynamic here, but in some cases it is needed.
{-# LANGUAGE DeriveDataTypeable #-}
import Data.Dynamic
data A = A deriving (Typeable)
data B = B deriving (Typeable)
f x | Just A <- fromDynamic x = 1
| Just B <- fromDynamic x = 2
f2 x | Just A <- cast x = 1
| Just B <- cast x = 2
main = do
print $ f (toDyn A)
print $ f2 A
Upvotes: 1
Reputation: 11963
No, this is not possible with a normal case statement, but you can hack this sort of thing using type classes:
data A = A
data B = B
class Test a where
test :: a -> Int
instance Test A where test = const 1
instance Test B where test = const 2
main = print $ test A
But you should only use this if it's really required, as it gets messy very soon and you end up with needing a lots of extensions to the type system (UndecidableInstances, OverlappingInstances, ...)
Upvotes: 1
Reputation: 363507
A
and B
are distinct types. If you want a function that can take values of multiple types, you need a typeclass.
data A = A
data B = B
class F a where
f :: a -> Int
instance F A where
f _ = 1
instance F B where
f _ = 2
main = do
print $ f A
Upvotes: 6