Closed JivanRoquet closed 3 years ago
After a bit of research, looks like there are two sides of this problem. First, there is a Database.Redis.PortNumber
constructor, which will not take a non-literal Int
. Second, there is a Network.Socket.PortNumber
type which will not accept a non-literal Int
as well.
So, neither of these will work:
import Database.Redis as Redis
import Network.Socket as NS
myValue = 6379
myValue :: NS.PortNumber -- nope
Redis.PortNumber myValue -- nope
Redis.PortNumber $ myValue :: NS.PortNumber -- not a chance
Redis.PortNumber $ myValue :: Redis.PortID -- try again
I'm absolutely certain that there must be a way to do this (I guess I'm not the only one trying to connect from dynamically loaded credentials instead of compile-time literals), but I haven't found any so far, and the documentation doesn't seem to say anything about this.
Yeah, it's somewhat weird, but the solution is to use a fromIntegral
method.
fetchRedisConnection :: RedisConfig -> ConnectInfo
fetchRedisConnection config =
defaultConnectInfo
{ connectHost = T.unpack $ redisHost config,
connectPort = PortNumber $ fromIntegral (redisPort config),
connectDatabase = redisDB config
}
Very neat, thanks a lot.
With the following configuration record:
I want to create a connection as follows:
But I couldn't find any way to make
PortNumber
accept anything else than a literalInt
. For instance,PortNumber 6379
works but even ifredisPort config == 6379
, doingPortNumber $ redisPort config
just won't make it. I tried explicitly typing as aPortID
or as anInt
, nothing works.This appears inconsistent with the
connectHost
field, which is perfectly happy with my non-literalString
even though it expects aHostName
.The compiler error that I get with the above code is as follows: