alanz
November 11, 2021, 11:32pm
1
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
5 Likes
jaror
November 12, 2021, 7:47am
3
I think this is slightly nicer:
f :: (Typeable a, Typeable b) => a -> b -> b
f x y = fromMaybe y (cast x)
5 Likes
alanz
November 12, 2021, 6:02pm
4
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.
amesgen
November 12, 2021, 8:40pm
5
This combinator (flipped) and many similiar ones are available in syb: Data.Generics.Aliases
2 Likes