Hi, all.
Let’s suppose I have existential type and function that unwrap the data:
data Value = forall a . (Typeable a, Read a) => Value a deriving stock Show
fromValue :: forall a . Typeable a => Value -> Maybe a
fromValue (Value v)
| typeOf v == typeRep (Proxy @a) = cast v
| otherwise = Nothing
and I have the following code:
data Http
= Http
{ getHttpHost :: !String
, getHttpPort :: !Word16
, getHttpBool1 :: !Bool
, getHttpBool2 :: !Bool
}
deriving stock (Show)
setHttp :: Http -> (String,Value) -> Http
setHttp x ("http-host", v) = x {getHttpHost = fromMaybe "" fromValue @String v}
setHttp x ("http-port", v) = x {getHttpPort = fromMaybe 0 fromMaybe @Int v}
I don’t like that boilerplate with fromMaybe
I’m trying to write the code that create default value automatically with help of Monoid, like this one, and the following example works for any Num type:
numDefault :: forall a . (Monoid a, Typeable a, Num a) => Value -> a
numDefault (Value v) = fromMaybe (getSum . mempty $ Sum @a) $ cast @_ @a v
But I can’t compose that function with another one, like in the next example, since ghc complains that I need to add Num type class here, however if I add it, it won’t work with Strings and Bool:
fromValue :: forall a . (Monoid a, Typeable a) => Value -> a
fromValue val@(Value v)
| typeOf v = typeRep (Proxy @Integer) = numDefault @a val
| otherwise = mempty @a
Does anyone know, how to implement that behaviour? I don’t any ideas since I don’t have enough knowledge.
I will appreciate for any hints