Type testing function

Hi all. I need a function to copy a value to another one, if I can. And can means the types match.

So I have in mind something like

-- If a and b are the same type return first arg, else return second
combine :: a -> b -> b

It feels like I should be using a generic query typed @b. But it is late and I am lazy so I am asking here.

1 Like

Like this?

import Data.Type.Equality
import Type.Reflection

-- >>> combine (1 :: Int) (2 :: Int)
-- 1
-- >>> combine (1 :: Int) (2 :: Word)
-- 2
combine :: (Typeable a, Typeable b) => a -> b -> b
combine a b = case testEquality (typeOf a) (typeOf b) of
    Just refl -> castWith refl a
    Nothing -> b

I think this is slightly nicer:

f :: (Typeable a, Typeable b) => a -> b -> b
f x y = fromMaybe y (cast x)

Thanks @taylorfausak and @jaror . Both variants do what I want, and I agree the second is simpler.

For some reason I had it in my head that cast could only be used with concrete types.

This combinator (flipped) and many similiar ones are available in syb: Data.Generics.Aliases